in reply to Re^2: Checking MD5 of files in directory with corresponding MD5 file type
in thread Checking MD5 of files in directory with corresponding MD5 file type

Why do you want to process both, "file" and "file.md5"?

I think you want to do something different with "file" than you want to do with "file.md5".

Also note that if you know "file", you also know "file.md5", and if "file.md5" is not found that is an error.

You can blindly open "file.md5" without needing to verify its existence beforehand.

  • Comment on Re^3: Checking MD5 of files in directory with corresponding MD5 file type

Replies are listed 'Best First'.
Re^4: Checking MD5 of files in directory with corresponding MD5 file type
by deedo (Novice) on Dec 30, 2016 at 11:09 UTC

    The way I was looking at it was that I would process the MD5 of 'file' and then open 'file.md5' and hold its content in memory to compare to the processed MD5 of 'file' - if that makes sense... then if it matches move to the next file and corresponding .md5 file and if there is an error, send it to the logmd5 subroutine for logging

      hold its content in memory

      Assuming the *.md5files contain just the value (single line ?) then consider reading them all first and use a hash to store the results for comparison later, for example

      #!perl # test.pl use strict; use warnings; use Cwd; use Digest::MD5; use Data::Dump 'pp'; my $sourcedirectory = cwd(); # '//path/to/directory' # create test file with md5 value open my $io_handle,'<','test.pl' or die "$!"; my $md5 = Digest::MD5->new; $md5->addfile($io_handle); close $io_handle; open OUT,'>','test.md5' or die "$!"; print OUT $md5->hexdigest; close OUT; # read md5 values into a hash my $md5values = get_md5values($sourcedirectory); pp $md5values; sub get_md5values { my $sourcefiles = shift; opendir(DIR, $sourcefiles) or die "Can't open directory, $!"; my @md5_files = grep /\.md5$/,readdir(DIR); closedir(DIR); my %md5 = (); for my $filename (@md5_files){ my $count = 0; open MD5,'<',$filename or die "$!"; while (<MD5>){ chomp; $md5{$filename} .= $_; ++$count; } close MD5; print "$count lines read from $filename\n"; } return \%md5; }
      poj

      OK. So, I see six steps in your plan:

      1. process the MD5 of 'file'
      2. and then open 'file.md5'
      3. and hold its content in memory
      4. (to) compare to the processed MD5 of 'file'
      5. then if it matches move to the next file and corresponding .md5 file
      6. if there is an error, send it to the logmd5 subroutine for logging

      Which parts of these have you already implemented and which are missing?

      Maybe it helps to write these either as print statements or as comments in your code, and then replace them one by one with real code:

      sub check_md5 { my( $path, $item ) = @_; # process the MD5 of 'file' # open 'file.md5' # hold its content in memory # compare to the processed MD5 of 'file' # if it matches move to the next file and corresponding .md5 file # if there is an error, send it to the logmd5 subroutine for logging };

      What is the first item you can implement? Do that, then do the next item from the list that you can implement. Do that until either you've implemented everything or until you get stuck.

        Spot on! Exactly what I am trying to achieve! I'll work on it after lunch and see where I get to - am off until Wednesday after today so it may be then that it gets finished. Thanks for all your help! I'll come back if I get to the point where I'm stuck. Many thanks!

        I've been distracted all afternoon, so it will be next week before I get a chance to look at this. Thanks again for your help and happy new year

        Hi Corion hope you're well, sorry I've not got back to you, I had to take a week off work due to family reasons. I'm back at the code today and am trying to follow the steps and suggestions you indicated before. So far, so good, but I have a problem with "blindly" opening the .md5 equivalent of the file I pass to the 'routine' subroutine

        The code I have so far is (with exclusion of the other subroutines which I know work fine):

        use strict; use warnings; use Digest::MD5; my $sourcedirectory = '//path/to/directory'; &main(); sub main { # creating file array my @files = &getfiles($sourcedirectory); # removal of the two directory structures which form the start of +the file array my $rmdir = shift (@files); my $rmdir2 = shift (@files); # capture of a count of the number of files remaining in the array my $filecount = @files; # check to see if there are no files, if none, exit script if ($filecount == 0) { print "\nNo files to process\n\n"; exit; } # where there are files, the routine subroutine is called for each + item individually (except for md5 file types) else { foreach my $item (@files) { next if $item =~ /.md5/; my $filepath = "$sourcedirectory/$item"; &routine($filepath, $item); } } } sub routine { # identify filepath and name as parameters passed to routine my $file = shift; my $name = shift; # open file, set to binary mode, close and process MD5 open my $fh, '<', $file or die "Can't open file: $!"; binmode ($fh); my $md5tocompare = &processmd5($fh); close $fh or die "Can't close file successfully: $!"; # check file.md5 existence and open and read to memory open my $fh2, '<', "$file.md5" or next; my $originalmd5 = <$fh2>; close $fh2 or die "Can't close file successfully: $!"; # check parity print "MD5 is $md5tocompare against orignal MD5 of $originalmd5\n" +; } ...

        Every time I run this code, the script exits the at the 'next' statement upon attempting to open the "$file.md5" handle. Do you have any idea what I am doing wrong here? I know the MD5 file exists so it is probably syntax or the way I am trying to get a handle on the file, but I'm at a loss at the moment. Tried it bare, with single and double quotes etc :)

        Any indicator you could provide would be appreciated

        Many thanks