Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^3: explanation for sysread and syswrite

by dbwiz (Curate)
on May 14, 2005 at 13:14 UTC ( #457046=note: print w/replies, xml ) Need Help??


in reply to Re^2: explanation for sysread and syswrite
in thread explanation for sysread and syswrite

That's better.

A few comments:

  • Always check the result of a file open or I/O operation.
  • You don't need to know the size of your file to use sysread. You can say how much sysread should read, and that function will return the number of bytes read, or 0 when it's finished.
  • If you really need to know the file size, use a -s check.

Here is an example.

#!/usr/bin/perl use warnings; use strict; my $filename = "stable.tar.gz"; # it's the latest Perl source code die "filename not found\n" unless -f $filename; my $size = -s $filename; my $total_read = 0; open F, "< $filename" or die "can't open $filename\n"; my $bufsize = 2_000_000; my $buffer; while ( my $read = sysread(F , $buffer , $bufsize, ) ) { printf "Read %8u bytes\n", $read; # do something with $buffer $total_read += $read; } print "initial size: $size\n"; print "total read: $total_read\n"; __END__ output: Read 2000000 bytes Read 2000000 bytes Read 2000000 bytes Read 2000000 bytes Read 2000000 bytes Read 2000000 bytes Read 254916 bytes initial size: 12254916 total read: 12254916

HTH

Replies are listed 'Best First'.
Re^4: explanation for sysread and syswrite
by bahadur (Sexton) on May 14, 2005 at 13:23 UTC
    thanks for that
    so if i give the buffer size the same as the size of the file what would happen. would it write the whole thing to the scalar at once or what?
Re^4: explanation for sysread and syswrite
by bahadur (Sexton) on May 14, 2005 at 13:38 UTC
    and hey how do i change the mode back to normal.
    like one mode is binmode. what is the other mode? how do i undo binmode?
      so if i give the buffer size the same as the size of the file what would happen. would it write the whole thing to the scalar at once or what?

      If you are reading from a disk file, you can get the file size using "-s $filename", and if you use the file size as the buffer size arg for sysread, the entire file will be read into your scalar variable. If you provide a buffer size arg bigger than the file size, sysread will read the entire file into the scalar, and the return value from sysread will be the number of bytes read (i.e. the file size). If your buffer-size arg is smaller than the actual file size, you'll get that many bytes from the file, and there will be more of the file that hasn't been read yet. This is what "while" loops are for:

      my $bufsize = 8192; # typical size for i/o buffers my ( $databuf, $readbuf, $nread ); while (( $nread = sysread( FH, $readbuf, $bufsize )) > 0 ) { $databuf .= $readbuf; } my $filesize = length( $databuf );

      That sort of approach is also handy when reading something other than a disk file (e.g. from a socket, pipeline, etc), where there's no way to determine in advance how much data is going to be coming in.

      how do i change the mode back to normal. like one mode is binmode. what is the other mode? how do i undo binmode?

      The standard, basic "binmode" call on a file handle is needed to tell certain operating systems (M$-Windows/DOS) that the file data should be conveyed to/from the file handle in its entirety and without modification of any kind .

      For these particular operating systems, the alternative (in fact, the "normal" default mode) is referred to as "text mode", in which the data going to or from a file handle is modified to adjust the line-termination characters to be CRLF (rather than the standard *n*x LF). This can be deadly if you're handling, say, audio or image data rather than text data. What happens is that the low-level i/o functions will add a CR character (carriage-return, 0x0d) wherever one is "needed" -- which is before each LF character (line-feed, 0x0a).

      Also, in text mode the ^Z character (0x1a) is used to explicitly mark "end-of-file" (which means that when the low-level i/o functions encounter one of these in a text-mode file handle, it will not read any more data from that file); you need binary mode in order to treat ^Z as just another data byte, and be able to read any file data that comes after it.

      So, if you need binmode to read or write a given file, then you don't need to think about using any other mode for that file, or "undoing" binary mode -- you don't want to do that.

      BTW, using binary mode on an actual text file is not really a problem, in most cases. It just means that nothing is done to alter the line termination characters, and sometimes this is a good thing.

      (Final note: as of Perl 5.8.x, the binmode function can also be used to specify that a file should be treated as using a particular character encoding, such as utf8 or iso-8859-1 or cp932 or whatever; if you read about PerlIO and binmode in 5.8.x, you'll find lots of useful information and techniques.)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://457046]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2020-10-20 18:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (210 votes). Check out past polls.

    Notices?