wileykt has asked for the wisdom of the Perl Monks concerning the following question:

I'm finalizing a client socket program. The files are being sent fine, I'd just like to add an error checker for the files before they're sent. My question is on how to best do this. Below is a snippet of code that I'm working with.
for (;;) { while (readdir OMSSEND) { @conffiles = grep { !/^\./ } readdir(OMSSEND); } foreach $file (@conffiles) { open FILE, "$senddir" . "/" . "$file" or die "Can't open: $!"; $server = IO::Socket::INET->new( PeerAddr => whatever, PeerPort => 11, Proto => 'tcp') or die "Can't connect to ..."; print $server $stx . $padsize or die "Can't send to server $!"; while (<FILE>) { print $server $_ or die "Can't send to server $!"; } close FILE;
I want to grep for errors in the file before the transmission starts, so I thought about writing a sub that looks almost like the main above, by reading in each files lines to an array, then grepping the array. If I find errors, I'll move the file to another directory so it can't be sent. My question is, this seems like alot of extra work to go through to do this, is there another way to search a file all at once before I open it in the above code to start the send process?
Thanks - wileykt

Replies are listed 'Best First'.
Re: Grep file before sending through socket
by dws (Chancellor) on Dec 08, 2001 at 01:55 UTC
    I want to grep for errors in the file before the transmission starts ... If I find errors, I'll move the file to another directory so it can't be sent. ... is there another way to search a file all at once before I open it in the above code to start the send process?

    Since you need to open the file before grepping it, try something like

    open FILE, "$senddir/$file" or die "$senddir/$file: $!" my $file = do { local $/; <FILE> }; close(FILE); if ( $file =~ m/$errors/mo ) { # move the file } else { # open the socket and send $file, as before } }
    where $errors is a regular expression that you set up in advance with the patterns that mean "error" to you. (Or, you can hard-code it). The /m on the regex allows you to use ^ and $ to match lines within $file.

      dws,
      Thanks, this works. I was wondering if you could help me interpret the following line.
      my $file = do { local $/; <FILE> };
      I know $/ is a line separator, but in this context, what is it doing? I'm fairly new to perl and some things are still cryptic to me. Thanks
        I was wondering if you could help me interpret the following line.   my $file = do { local $/; <FILE> }; This is called "slurp mode". Setting $/ to undef means that the entire file will be read. Localizing $/ within a short-lived scope both sets $/ to undef, and ensures that it will be restored on scope exit.

        This is equivalent in effect to writing   my $file = join('', <FILE>); but without the extra overhead to build up a temporary array and set of strings to populate it with.

Re: Grep file before sending through socket
by DrManhattan (Chaplain) on Dec 08, 2001 at 04:39 UTC
    Just a note:
    while (readdir OMSSEND) { @conffiles = grep { !/^\./ } readdir(OMSSEND); }
    The while() loop there is superfluous. The first readdir() reads off the first entry since it's called in scalar context, then the grep() reads off all the rest in one go since it calls readdir() in array context. The while loop only executes once, and your grep always misses the first file. Since the first file is always "." and you're grepping to get rid of it anyway, the loop doesn't hurt anything, but it isn't doing quite what you intended. :)

    -Matt