- 论坛徽章:
- 1
|
There may cases where you need to read a file only a few characters at a time instead of line-by-line. This may be the case for binary data. To do just that you can use the read command.
open FILE, "picture.jpg" or die $!;
binmode FILE;
my ($buf, $data, $n);
while (($n = read FILE, $data, 4) != 0) {
print "$n bytes read\n";
$buf .= $data;
}
close(FILE);
There is a lot going on here so let's take it step by step. In the first line of the above code fragment a file is opened. As you can guess from the filename it is a binary file. Binary files need to treated differently than text files on some operating systems (eg, Windows). The reason is that on these platforms a newline "character" is actually represented within text files by the two character sequence \cM\cJ (that's control-M, control-J). When reading the text file Perl will convert the \cM\cJ sequence into a single \n newline characted. The converse also holds when writing files. Clearly, when reading binary data this behavior is undesired and calling binmode on the filehandle will make sure that this conversion is avoided.
The read command takes either 3 or 4 arguments. The 3-argument form is:
read FILEHANDLE, SCALAR, LENGTH
while the 4-argument form is:
read FILEHANDLE, SCALAR, LENGTH, OFFSET
In the first case LENGTH characters of data are read in the variable specified by SCALAR from FILEHANDLE. The return value of read is the number of characters actually read, 0 at the end of the file or undef in the case of an error. Returning to our example above the third line of code will read at most 4 characters of data into the $data variable. The number of characters read will be stored in $n. Successive read operations on the same filehandle will set the current file position to be just before the first unread character. Thus the code above will read the contents of the file picture.jpg and store them in $buf, printing the number of characters read at every iteration.
If OFFSET is specified then the characters read will be placed at that position within the SCALAR. Taking advantage of this we could rewrite the loop above as such:
my ($data, $n, $offset);
while (($n = read FILE, $data, 4, $offset) != 0) {
print "$n bytes read\n";
$offset += $n;
}
Even though the example above demonstrates binary reading the read command works just as well on text files - just make sure to use (for binary) or not use (for text) binmode accordingly. |
|