sub _read { my ($fh, $bytes_to_read) = @_; my $buf = ''; while ($bytes_to_read) { my $bytes_read = read($fh, $buf, $bytes_to_read, length($buf)); if (!$bytes_read) { die "Error reading: $!\n" if !defined($bytes_read); die "Unexpected EOF\n"; } $size -= $bytes_read; } return $buf; } sub read_uint32 { my ($fh) = @_; unpack('N', _read($fh, 4)) } #Or V? sub read_uint16 { my ($fh) = @_; unpack('n', _read($fh, 2)) } #Or v? sub read_pstring { my ($fh) = @_; _read($fh, read_uint16($fh)) } { open(my $fh, '<:raw', $datfilename) or die $!; read_uint32($fh); while (!eof($fh)) { my $profile_id = read_uint32($fh); my $seq1 = read_pstring($fh); my $seq2 = read_pstring($fh); read_uint16($fh); ... } }