Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

File and Folder length problems

by merrymonk (Hermit)
on Oct 01, 2015 at 19:12 UTC ( [id://1143595]=perlquestion: print w/replies, xml ) Need Help??

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

I have had
a. failures to get the mtime value usng the mtime value from 'stat' of a file
b. Can't cd to .. using File:Find
for files and folders with more than 250 characters in their names.
Am I right in thinking that the failures are due to the length of the names?
If so, is there a simple way of overcoming this limit?

Replies are listed 'Best First'.
Re: File and Folder length problems
by dasgar (Priest) on Oct 01, 2015 at 22:05 UTC

    What OS are you using?

    My guess is that you could be on Windows. Although the NTFS filesystem does support longer path lengths, the predominate API that most Windows programs use has a max path length of ~250-260 characters for backwards compatibility. (I've seen different documentation referencing different values on what that max value is.) And most of the Perl modules (including File::Find) uses the API with the ~250-260 character limit on paths.

    On Windows, I have encountered the issue described in File::Find's bug report #44819 about getting a "Can't cd" error message that has a lot of "/../" directories in the path. It's been a while since I hit that issue and if I remember correctly, using the no_chdir option of File::Find did not fix the issue. After modifying the source of File::Find as described in that bug report, I was able to get around the issue.

    If you do decide to try using that, just keep in mind that the source code of the newer versions of File::Find is different and the portion that would need to be modified is not going to look exactly like what is described in the bug report. It's been a while since I tried using that, so I can't give you more details on what to look for. I should also point out that I don't know what the full effect of modifying File::Find's source as described in the bug report, which means that doing so may create problems. So proceed with caution if you want to try that work around.

    Even if you're willing to try to modify your copy of File::Find as described above, you will still have issues if your path length exceeds the max path length of that Windows file API. I've recently been trying to figure out how to traverse a directory structure in Windows for directory structures that I know exceed the ~250-260 character limit. If I remember correctly, Path::Tiny (as suggested by GotToBTru) still had the same path length issue. Just wanted to point that out in case you really do have a genuine long path (> ~250-260).

    If you do have long paths that you are working with, you might find Win32::LongPath to be useful - and it does provide a statL function that can provide mtime information that you are looking for. I have not tried looking into getting other modules (File::Find, Path::Tiny, etc.) to leverage Win32::LongPath, so I can't provide any guidance with that. I was able to use the logic from Re: Win32 Recursive Directory Listing and Win32::LongPath to successfully traverse a directory structure that had paths with more than 300 characters. In that code, I did leverage Path::Tiny to manipulate paths (basename, cannonpath, etc.) as long as I avoided using Path::Tiny to access the long paths (opening/reading files and directories, file copying, etc.).

Re: File and Folder length problems
by stevieb (Canon) on Oct 01, 2015 at 19:31 UTC

    It would really help if you had of showed us your code (please edit your question with the code, putting it within <code></code> tags), but regardless, using the no_chdir parameter to File::Find often helps work around these issues:

    use warnings; use strict; use File::Find; my $dir = '.'; find ({ wanted => \&wanted, no_chdir => 1 }, $dir); sub wanted { print "$File::Find::name\n" if -f; }

    Note that when using the no_chdir param (or any other params for that matter), all params less the directory to search must be passed in within a hash reference per above. Also note that when you're using no_chdir, you won't get the full file path by default, so as I've illustrated in the above code, simply use $File::Find::name to get the filename as "/full/path/to/file.ext".

    -stevieb

Re: File and Folder length problems
by choroba (Cardinal) on Oct 01, 2015 at 19:57 UTC
    What OS? I'm on linux with ext4:
    $ perl -MPath::Tiny -lwE 'path("a" x 256)->touch' Error open (>) on 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa': + File name too long at -e line 1.
    $ perl -lwe 'for my $p ("./" x 2047, "." x 2048) { @s = stat $p ;print + for @s ? @s : $! }' 2051 44564481 16877 128 1000 100 0 24576 1443729279 1443729280 1443729280 4096 56 File name too long
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: File and Folder length problems
by GotToBTru (Prior) on Oct 01, 2015 at 20:29 UTC
    1. Need to see your code for this one. Also show directory listing for the target directory.
    2. File::Find will go deeper into a directory tree, but I have not seen it go shallower as cd .. would do.

    You might find Path::Tiny a help in navigating around directories.

    Dum Spiro Spero
Re: File and Folder length problems
by Anonymous Monk on Oct 01, 2015 at 22:04 UTC

    Am I right in thinking that the failures are due to the length of the names?

    Did you check errno?

    $ perl -MPath::Tiny -le " path( q/goner/, map { 1 } 1 .. 117 )->touchp +ath; path(q/goner/)->remove_tree " mkpath failed for goner/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/ +1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1 +/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/ +1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1: No such file or dire +ctory; The filename or extension is too long at -e line 1. $ perl -MPath::Tiny -le " path( q/goner/, map { 1 } 1 .. 116 )->touchp +ath; path(q/goner/)->remove_tree " $ perl -MPath::Tiny -le " $f=path( q/goner/, map { 1 } 1 .. 116 )->tou +chpath; print scalar(gmtime($f->stat->mtime)); path(q/goner/)->remove +_tree " Thu Oct 1 22:07:21 2015

Log In?
Username:
Password:

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

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

    No recent polls found