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

Win32::LongPath seems to be exactly what I need to deal with the files... but.. I can't get the rename function to work. This with Perl 5.32 on Win10/64. Anyone have any experience with this module? Is it possible to contact the author?

my test code is very simple

#!/usr/bin/perl use v5.10 ; use strict; use warnings ; use Win32::LongPath ; my $d = Win32::LongPath->new() ; $d->opendirL(".") or die "Can't open directory: $!\n" ; for my $file ($d->readdirL()) { say $file ; } $d->renameL("testfile.txt", "testedfile.txt") or die "didn't rename! $ +!"; exit ;
and when I run it I get
D:\Desktop\test>rename.pl . .. rename.pl testfile.txt didn't rename! at D:\Desktop\test\Onefile\test\rename.pl line 12.
and indeed the file wasn't renamed. I haven't a clue what I'm doing wrong

Replies are listed 'Best First'.
Re: Contacting the author of a module?
by hv (Prior) on Jan 06, 2023 at 03:24 UTC

    I don't use Windows, but I note that the documentation for Win32::LongPath doesn't show renameL as a method you can call on the directory handle returned by opendirL, but only shows its use as a function - and the examples are all using absolute paths:

    # should work renameL ('c:/file', 'c:/newfile'); # fails, can't move file to directory renameL ('d:/file', '.'); # should work for files renameL ('e:/file', 'f:/newfile'); # should work renameL ('d:/dir', 'd:/topdir/subdir'); # fails, can't move directory across volumes renameL ('c:/dir', 'd:/newdir');

    So I think you should try using it as documented, and see if that works better. It is also possible that it will treat relative paths as being relative to the current directory, but I suggest trying that second after verifying that it works as documented for absolute paths.

      Great catch! I missed that. and as you suggested: using it properly works like a champ. THANKS!
        I expect that none of you really care about this or will run into this problem, but y'all were so helpful as I wandered on my fool's errand I'd like to share the end result of it. You might be amused at the way I got rid of the Unicode characters.. :o)
        #!/usr/bin/perl # Remove the Unicode characters from file names # $Id: removeunicode.pl 1.2 2023/01/07 00:21:49 bernie Exp $ use v5.10 ; use strict; use warnings ; use Getopt::Std ; # getopts(<flags>, \%args) ; my %args ; use Win32::LongPath ; getopts("v", \%args) or Usage(); sub Usage { die "Usage: removeunicode [-v] <DIR>\n" ; } my $dir = $ARGV[0] ; Usage() unless $dir ; chdir $dir or die "can't connect to $dir: $!\n" ; trace("connected to $dir") ; my $d = Win32::LongPath->new() ; $d->opendirL(".") or die "Can't open $dir: $!\n" ; for my $file ($d->readdirL($d)) { my $fixedfile = sanitize($file) ; next if $fixedfile eq $file ; # No unicode this filename trace("working on $file") ; trace("changing to $fixedfile") ; renameL($file, $fixedfile) or die "didn't rename! $!"; } exit ; #Remove all the unicode characters from a string sub sanitize { my $unicode = $_[0] ; my $ascii ; for my $char (split(//, $unicode)) { $ascii .= $char if ord($char) < 256 } return $ascii; } sub trace { say $_[0] if $args{v} }
Re: Contacting the author of a module?
by ikegami (Patriarch) on Jan 06, 2023 at 18:55 UTC

    Also, use $^E (Windows's GetLastError), not $! (C's errno).

    >perl -MWin32::LongPath -E"renameL('a','b') or die qq{renameL: $!\n}" renameL: >perl -MWin32::LongPath -E"renameL('a','b') or die qq{renameL: $^E\n}" renameL: The system cannot find the file specified
Re: Contacting the author of a module?
by syphilis (Archbishop) on Jan 06, 2023 at 11:42 UTC
    Win32::LongPath seems to be exactly what I need to deal with the files...

    What is it about this module that appeals to you ?

    I generally find it very annoying when someone responds to a simple question by asking the question that I've just asked - so I apologize for asking it.
    It's just that, in one of my scripts, I have found a need to call on (the similarly named) Win32::GetLongPathName function - and I wonder if that function might also serve your needs.

    Essentially, I just use Win32::GetLongPathName() for case-sensitive checking of filenames on Windows.

    Cheers,
    Rob

      See earlier question. The builtins of Windows builds of Perl can't deal with file name with characters outside of the system's Active Code Page (e.g. 1252 on my system). But this module can.

      I have a bunch of files with filenames that are all filled with Unicode stuff. I've always been a bit confused by how Unicode and ISO-Latin co-exist in Perl and I've really never had any need for Unicode so I've not worried about it much. The *only* thing I want to do with these files is fix their names by eliminating the Unicode stuff. I expect that the more unicode competent Perl folk will be horrified, but this is the routine I use to un-Unicode the file names:
      #Remove all the unicode characters sub sanitize { my $unicode = $_[0] ; my $ascii ; for my $char (split(//, $unicode)) { $ascii .= $char if ord($char) < 256 } return $ascii; }

        Your sub is equivalent to

        sub sanitize { $_[0] =~ s/[^\x00-\xFF]//gr }

        But it's wrong if you're trying to generate file names Perl can handle. cp1252 can't encode U+0080 to U+009F except U+0081, U+008D, U+008F, U+0090 and U+009D. Fixed:

        sub sanitize { decode( "cp1252", encode( "cp1252", sub{ "" } ) ) }
Re: Contacting the author of a module?
by GrandFather (Saint) on Jan 06, 2023 at 01:30 UTC

    The contact email address for the author is rboisvert@cpan.org.

    Is there already a file with the new name?

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond