Reading a dynamic record length binary file
open (FILE, $ARGV[0]) or die $!;


It won't really make a difference in this script, but the standard is to use a variable rather than a bareword.  

open (my $fh, $ARGV[0]) or die $!;


This gives you the benefits of lexical scoping.  

while (&lt;FILE&gt;) {


What this says is while there are still lines in &lt;FILE&gt;, do the things in the block.  It separates lines by the line ending marker, which is normally a linefeed.  This would normally be used:  

while ( my $line = &lt;$fh&gt; ) {
    chomp $line;


Then you could break the line up into parts with unpack.  

    my ( $field1and2, $vector_count, $field4, $vector_field ) = unpack( 'A2395 A3 A254 A*', $line );


Note that I may have the format wrong.  It's easier if one can test against a valid file.  You may not even need that much:

    my ( undef, $vector_field ) = unpack( 'A2652 A*', $line );


It seems like you only use the vectors portion.  

Instead, you use the while loop just to keep count.  However, that wouldn't normally work unless records were terminated with linefeeds.  

open (my $fh, $ARGV[0]) or die $!;
while ( my $line = &lt;$fh&gt; ) {
    chomp $line;

    filewrite ($ARGV[1], recordparse($line));
}


See how that's simpler?  No more seeks.  This doesn't even require unpack, as it looks like you pass the whole line to recordparse.

One more thing:

filewrite ($ARGV[1], recordparse($string));


I'm not sure what this function does, but it looks like it takes a file name and writes to it.  This suggests that it opens the file each time.  Better would be to open the file once and pass a filehandle to it.  



If you were getting multiple records with the original code but there are no linefeeds in the file, then I suspect that the seek and read commands are resetting the line input operator.  

Alternate version to handle reading the entire file at once (assumes no linefeeds in the data).  

open (my $fh, $ARGV[0]) or die $!;
my $file = &lt;$fh&gt;;
while ( '' ne $file ) {
    my $rep_factor = substr $file, 2396, 3;
    my $vector_count = undefined2defined(convert2ascii_decimal($rep_factor, 0));
    my $size = ($vector_count * 301) + 2652;

    my $record = substr $file, 0, $size;
    $file = substr $file, $size;

    filewrite ($ARGV[1], recordparse($record));
}


This uses substr rather than unpack because it's easier to specify different lengths with substr.  The first version asks for $size bytes starting at the beginning.  The second version says to return everything but the first $size bytes.  

I'm a little worried that there is some maximum length that the &lt;&gt; operator returns, but I don't know what it might be.  Since I don't have an example file, I'm not testing the code at all.