Search Unity

File.Move for filepaths longer then 260 characters

Discussion in 'Scripting' started by Rob-Reijnen, Feb 1, 2022.

  1. Rob-Reijnen

    Rob-Reijnen

    Joined:
    Oct 14, 2013
    Posts:
    60
    I need to rename some files in my application that are placed somewhere on the pc.
    First I am getting every file path in a directory. And then I use File.Move to rename it.

    Every file path that is longer then 260 chars would not work and would give me an error saying the file does not exist.

    FileNotFoundException: "Some/300/characters/long/path.png" does not exist

    However Directory.GetFiles IS actually retrieving the files with the long names.

    I can also log the file path and go to it in Windows explorer. And therefore I can verify it really does exist. I have verified that the problem is the path length.


    I can not manually shorten the file name, because it needs to work dynamically with all possible files. And non-coders need to use the software, using their own images.

    Code (CSharp):
    1.                 foreach(string file in Directory.GetFiles(folderpath))
    2.                 {
    3.                     File.Move(
    4.                        file,
    5.                        newName
    6.                         );
    7.                 }
    How can I rename, or read a file that has a longer file path then 260 characters?
     
  2. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    valentine_velchev and Bunny83 like this.
  3. Rob-Reijnen

    Rob-Reijnen

    Joined:
    Oct 14, 2013
    Posts:
    60
    Hi Thanks,

    I did already try that out. But doing that it won't recognize any file anymore. So it doesn't seem to pick up that prefix as I intended.
     
  4. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    Hmm damn - sorry that didn't help. Fascinating problem - hope someone comes along with an answer cause now I wanna know.
     
  5. Rob-Reijnen

    Rob-Reijnen

    Joined:
    Oct 14, 2013
    Posts:
    60
    Nevermind! It worked!

    \\?\ wasn't working for me because my path name also contained / instead of using only \
    So I converted the file path:
    Code (CSharp):
    1. file.Replace("/","\\");
    And now it works with the \\?\ prefix.

    Thanks a lot!
     
    Cameron_SM and Bunny83 like this.
  6. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    @Rob-Reijnen That's wild! - really surprised I've never encountered this before.
     
  7. Zultron

    Zultron

    Joined:
    Dec 26, 2012
    Posts:
    59
    Just encountered it throws my commit of. Has ANyone found a solution?
     
  8. ilya_m_3ds

    ilya_m_3ds

    Joined:
    Jan 15, 2020
    Posts:
    9
    This post is incredible. Solved my long path issue as well.

    Thanks @Cameron_SM and @Rob-Reijnen for both of your efforts!
     
  9. Sammonius

    Sammonius

    Joined:
    Mar 18, 2017
    Posts:
    8
    Hi All,

    I also had the same FileNotFoundException when I tried to write a more than 259 chars long file path.

    I started using this "\\?\" prefix, and use only "\" chars, but I get this error:
    Win32 IO returned ERROR_INVALID_NAME. Path: \\?\D:\SquareLine Projects\Empty\components\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqwertzuiop.ecomp

    Does anybody have an idea?

    Thanks
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,003
    There are two limitations at play here. The 260 character limit is an API limit that is the result of backwards compatibility. A lot of Win APIs are still bound to this limit but there are workarounds / different APIs that work with longer paths. However this 260 character limit affects the whole path. There are additional limits for how long individual filenames can be. This depends on several factors, mostly the file system. NTFS has a limit of 256 characters per entry. So individual file and folder names can't be longer than 256 characters Your filename
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqwertzuiop.ecomp

    has 263 characters, That's not possible.

    So you could have 5 nested folders, each with a name of say 200 characters and a filename with 240 characters which would give you a path length of 3 + 5*200 + 240 == 1243 characters and this should work with the prefix. However a single entry in the path must not be longer than 256 characters.

    ps: The "260" limit actually was also 256. It's the path without the drive (D:\) and without the null terminating character that most WinAPIs require.

    pps: Why would you need a file name that is longer than 256 characters? That's just insane ^^
     
  11. John-davis78

    John-davis78

    Joined:
    Apr 6, 2024
    Posts:
    2
    You're running into the limitation of the maximum path length in Windows, which is indeed 260 characters. However, since .NET Framework 4.6.2 and .NET Core 2.0, there's a way to overcome this limitation by using the `\\?\` prefix to specify an extended-length path. Here's how you can modify your code to handle long file paths:

    ```csharp
    foreach(string file in Directory.GetFiles(folderpath, "*", SearchOption.AllDirectories))
    {
    string newFilePath = Path.Combine(folderpath, "newname.txt"); // Modify this to generate the new file path dynamically
    string extendedFilePath = @"\\?\" + Path.GetFullPath(file); // Prefixing with \\?\ to support long paths

    File.Move(
    extendedFilePath,
    newFilePath
    );
    }
    ```

    Here are the changes made:

    1. Use `SearchOption.AllDirectories` to search recursively through all directories.
    2. Prefix the file path with `\\?\` to enable support for extended-length paths.
    3. Generate the new file path dynamically according to your requirements.

    This should allow you to handle file paths longer than 260 characters.


    Or you can use LongPath Tool, simple as that.
     
  12. martinmillerr85

    martinmillerr85

    Joined:
    Mar 29, 2024
    Posts:
    2
    I used this above code:

    ```csharp
    foreach(string file in Directory.GetFiles(folderpath, "*", SearchOption.AllDirectories))
    {
    string newFilePath = Path.Combine(folderpath, "newname.txt"); // Modify this to generate the new file path dynamically
    string extendedFilePath = @"\\?\" + Path.GetFullPath(file); // Prefixing with \\?\ to support long paths

    File.Move(
    extendedFilePath,
    newFilePath
    );
    }
    ```
    but it didn't work. Then, I installed Long Path Tool. It has helped though.
     
  13. Rickeymarchram89

    Rickeymarchram89

    Joined:
    Apr 5, 2024
    Posts:
    2
    Has anyone found the solution yet? Character path limit can easily be solved by various tools. Has anyone used any of the tools such as longpath tool?