Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Moving files and directories

by perlNinny (Beadle)
on May 08, 2009 at 23:46 UTC ( [id://762969]=perlquestion: print w/replies, xml ) Need Help??

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

I have had no luck trying to ever just get the directory size, let alone move files and directories with files. Here is my unsucessful code:
use strict; use File::Copy; # yes, it is Windows XP and a drive letters assigned to a USB and a NA +S drive. # Indir and outdir will be a parameter in this format. my $inDir = "M:\AllFiles"; my $outDir = "n:\allFiles"; # test 1 straight in out in DOS format. MoveFiles($inDir,$outDir); # test 2 Try within quotes. MoveFiles("$inDir","$outDir"); # test 3 Try selecting ALL files in the directory MoveFiles($inDir."\*", $outDir); sub MoveFiles { my ( $source, $destination ) = @_; print "indir= $source, outdir=$destination\n"; my $source_size = (-s "$source") || 0; my $destination_size = (-s $destination) || 0; print "indir size=$source_size outdir size=$destination_size\n"; }
The results are three beeps plus this output:

indir= M:AllFiles, outdir=n:llFiles
indir size=0 outdir size=0
indir= M:AllFiles, outdir=n:llFiles
indir size=0 outdir size=0
indir= M:AllFiles*, outdir=n:llFiles
indir size=0 outdir size=0

So, what am I doing wrong?

Replies are listed 'Best First'.
Re: Moving files and directories
by Nkuvu (Priest) on May 09, 2009 at 00:00 UTC

    Inside of double quotes, backslashes need to be escaped. Try my $inDir = "M:\\AllFiles" (and correcting other backslashes as well).

    Note that if you had use warnings; at the top of the script, you'd see errors like "Unrecognized escape \A passed through scriptname.pl at line 8" which would be a flag indicating a potential problem.

      Thanks, but there is still problems:
      I get this output:
      indir= M:\AllFiles, outdir=n:\allFiles
      indir size=0 outdir size=0
      indir= M:\AllFiles, outdir=n:\allFiles
      indir size=0 outdir size=0
      indir= M:\AllFiles\*, outdir=n:\allFiles
      indir size=0 outdir size=0

      This tells me that the -s function isn't working
      which means it still isn't reading the directory information
      Eventually, I want to check to see if there is enought
      room, then execute a move function.
      use strict; use warnings; use File::Copy; # yes, it is Windows XP and a drive letters assigned to a USB and a NA +S drive. # Indir and outdir will be a parameter in this format. my $inDir = "M:\\AllFiles"; my $outDir = "n:\\allFiles"; # test 1 straight in out in DOS format. MoveFiles($inDir,$outDir); # test 2 Try within quotes. MoveFiles("$inDir","$outDir"); # test 3 Try selecting ALL files in the directory MoveFiles($inDir."\\*", $outDir); sub MoveFiles { my ( $source, $destination ) = @_; my $source_size = (-s $source) || 0; my $destination_size = (-s $destination) || 0; move( $source, $destination ) if ($destination_size > $source_size); }

        On win32 systems, stat often returns 0 for size when called for a directory. Some documentation suggests that it may sometimes return non-zero for directory size in some circumstances, but I haven't seen it myself. The '-s' file test is based on stat, so '-s' will often return 0 when used on a directory.

        It might help you solve your problem if you check the return from the move function. See File::Copy for details. Maybe something like the following:

        move( $source, $destination ) or die "move( $source, $destination ) fa +iled: $!";

        The error message should help you understand why the move failed. On the other hand, testing I have done on Windows XP suggests that the error messages are not very good: in my tests it returned "No such file or directory" regardless of what the actual problem was. Also, while move worked for directories within a file system, copy didn't. Neither move nor copy worked for directories when moving or copying from one drive to another but move and copy both worked when moving or copying a file from one drive to another. So it seems that File::Copy is somewhat broken, at least for Active State perl 5.10.0 on Windows XP.

Re: Moving files and directories
by bichonfrise74 (Vicar) on May 09, 2009 at 00:03 UTC
    Just out of curiosity, what happens when you pass an actual file? Eg.
    my $inDir = "M:\AllFiles\test.txt"; my $outDir = "n:\allFiles\abc.txt";
    And I would guess that you need to read each size of your files in your directory and then add them up.
      Ask and ye shall receive
      With this code:
      use strict; use warnings; use File::Copy; # yes, it is Windows XP and a drive letters assigned to a USB and a NA +S drive. # Indir and outdir will be a parameter in this format. my $inDir = "M:\\AllFiles"; my $outDir = "n:\\allFiles"; # test 1 straight in out in DOS format. MoveFiles($inDir,$outDir); $inDir = "M:\\AllFiles\\TestDoc.txt"; $outDir = "n:\\allFiles\\abc.txt"; # test 2 Try specific files. MoveFiles($inDir,$outDir); $inDir = "M:\\AllFiles"; $outDir = "n:\\allFiles\\"; # test 3 Try selecting ALL files in the directory MoveFiles($inDir."\\*", $outDir); sub MoveFiles { my ( $source, $destination ) = @_; print "indir= $source, outdir=$destination\n"; my $source_size = (-s $source) || 0; my $destination_size = (-s $destination) || 0; move( $source, $destination ); print "indir size=$source_size outdir size=$destination_size\n"; }
      indir= M:\AllFiles, outdir=n:\allFiles
      indir size=0 outdir size=0
      indir= M:\AllFiles\TestDoc.txt, outdir=n:\allFiles\abc.txt
      indir size=18 outdir size=0
      indir= M:\AllFiles\*, outdir=n:\allFiles\
      indir size=0 outdir size=0
      I get the abc.txt in the n:\allfiles but the rest are left in the m:\Allfiles directory.
Re: Moving files and directories
by Marshall (Canon) on May 09, 2009 at 01:52 UTC
    You have some problems here.
    There are more efficient ways to do this with Perl, but you could just use the Windows Xcopy command.

    Here is just an example...

    C:\Projects>help xcopy Copies files and directory trees. XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [ +/W] [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T +] [/U] [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/EXCLUDE:file1[+file2][+file3]...] source Specifies the file(s) to copy. destination Specifies the location and/or name of new files. /A Copies only files with the archive attribute set, doesn't change the attribute. /M Copies only files with the archive attribute set, turns off the archive attribute. /D:m-d-y Copies files changed on or after the specified date. If no date is given, copies only those files whose source time is newer than the destination time. /EXCLUDE:file1[+file2][+file3]... Specifies a list of files containing strings. Each str +ing should be in a separate line in the files. When any of + the strings match any part of the absolute path of the file + to be copied, that file will be excluded from being copied. +For example, specifying a string like \obj\ or .obj will ex +clude all files underneath the directory obj or all files wit +h the .obj extension respectively. /P Prompts you before creating each destination file. /S Copies directories and subdirectories except empty ones +. /E Copies directories and subdirectories, including empty +ones. Same as /S /E. May be used to modify /T. /V Verifies each new file. /W Prompts you to press a key before copying. /C Continues copying even if errors occur. /I If destination does not exist and copying more than one + file, assumes that destination must be a directory. /Q Does not display file names while copying. /F Displays full source and destination file names while c +opying. /L Displays files that would be copied. /G Allows the copying of encrypted files to destination th +at does not support encryption. /H Copies hidden and system files also. /R Overwrites read-only files. /T Creates directory structure, but does not copy files. D +oes not include empty directories or subdirectories. /T /E incl +udes empty directories and subdirectories. /U Copies only files that already exist in destination. /K Copies attributes. Normal Xcopy will reset read-only at +tributes. /N Copies using the generated short names. /O Copies file ownership and ACL information. /X Copies file audit settings (implies /O). /Y Suppresses prompting to confirm you want to overwrite a +n existing destination file. /-Y Causes prompting to confirm you want to overwrite an existing destination file. /Z Copies networked files in restartable mode. The switch /Y may be preset in the COPYCMD environment variable. This may be overridden with /-Y on the command line.
      So I guess the answer is that there is no perl way to do this...use the syetem.
      Thanks for your help.
        I am saying that the the Windows XCOPY command is simple. It XCOPY is stupid and doesn't do all that would be desired. Send me a msg if you want to hear more...
Re: Moving files and directories
by afoken (Chancellor) on May 09, 2009 at 00:59 UTC

    Why don't use use xcopy+deltree or move?

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      The moving of files and directories are AFTER another operation within a perl script.

        You can call external programs like xcopy, deltree and move from whithin perl, on Win32 typically with system() or Win32::Process.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-20 02:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found