Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: bullet proof SLURP file

by haukex (Archbishop)
on Jan 09, 2018 at 19:47 UTC ( [id://1207009]=note: print w/replies, xml ) Need Help??


in reply to bullet proof SLURP file

my $x = <$f>; $! and croak "can't read mydata.txt: $!";

This is incorrect, since Perl does not guarantee that $! is cleared on a successful read. You'll have to check for errors by checking the return value of readline:

open my $fh, '<', 'mydata.txt' or die $!; defined( my $data = do { local $/; <$fh> } ) or die $!; close $fh or die $!;

But may I ask why you need this level of error checking? Are you reading from some kind of network resource for example? Because if it's just a regular file from a local harddisk, failures on e.g. close are pretty rare.

If you really do need this level of security, then one possible solution is using read and making sure the number of bytes read matches the file size - however, the following makes sense only if this is a plain ASCII or binary file, the file is not too huge, and note that the following has a theoretical race condition if someone else happens to be writing to the file at the same time as you're reading from it:

open my $fh, '<:raw', 'mydata.txt' or die $!; my $size = -s $fh; read($fh, my $data, $size) == $size or die $!; close $fh or die $!;

Replies are listed 'Best First'.
Re^2: bullet proof SLURP file
by leszekdubiel (Scribe) on Jan 09, 2018 at 20:58 UTC
    This is a program that computes data for manufacturing in company. I have to be sure that when data read from local file is broken in the middle of the process of reading, then the whole program fails. I will do that with "define" as you showed. If I read from a pipe (pipe open), then it fails on close if pipe is broken -- this is why I check exit status of close.
      If I read from a pipe (pipe open), then it fails on close if pipe is broken -- this is why I check exit status of close.

      Yes, checking the return value of close is very important on piped opens - as per its documentation:

      close $fh or die $! ? "Error closing pipe: $!" : "Piped open exit status: $?";
      when data read from local file is broken in the middle of the process of reading

      It depends a bit on what "broken" means - if you are always reading from a pipe, then yes, you should be able to detect this condition. However, if you're reading from a regular file, then I don't think the reading program will be able to detect a failure in the writer, if that is what you mean. If the file format allows for any kind of sanity checks (like headers with record lengths or other well-formedness checks), or even checksums, then I would use those.

      This is a program that computes data for manufacturing in company. I have to be sure that when data read from local file is broken in the middle of the process of reading, then the whole program fails.
      I have worked with many HD's that have either hardware errors or file system errors (usually both types of errors occur at the same time). Your original Perl program will abend with a fatal error if the complete HD file cannot be read. It is possible to open a file which cannot be successfully read to the EOF.

      close() does a lot for a "writer" -> flushes unwritten cached stuff to the HD. Not so much is done for a reader. A close() on a read handle does not modify the actual file that is being read. Again, that is not true on a write handle.

      Your original program will fail if the file is corrupted. Let's say that happens, then what is your "Plan"? A redundant disk system is probably what is needed.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-03-29 01:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found