Error: File Path is Too Long

后端 未结 4 1049
没有蜡笔的小新
没有蜡笔的小新 2021-01-18 17:57

i am trying to use the various file functions in C# like File.GetLastWriteTime, copy command on the file placed at the path greater than maximum allowed path on

相关标签:
4条回答
  • 2021-01-18 18:06

    As far as I know, you can't access a file directly if its path is too long (by directly, I mean using the methods of File, by creating a FileInfo via the constructor, or by using Directory.GetFiles(string fileName).

    The only way I've found that will let you access such a file is to access a directory somewhere in the path before it gets too long, and then programatically walk down the tree until you get to your file, as seen here.

    I've taken my code from there and modified it a little to return a FileInfo object for a file with a path that is "too long". Using this code, you can access the necessary properties on the returned FileInfo object (like LastWriteTime). It still has some limitations though, like the inability to use functions like CopyTo() or OpenText().

    // Only call GetFileWithLongPath() if the path is too long
    // ... otherwise, new FileInfo() is sufficient
    private static FileInfo GetFile(string path)
    {
        if (path.Length >= MAX_FILE_PATH)
        {
            return GetFileWithLongPath(path);
        }
        else return new FileInfo(path);
    }
    
    static int MAX_FILE_PATH = 260;
    static int MAX_DIR_PATH = 248;
    
    private static FileInfo GetFileWithLongPath(string path)
    {
        string[] subpaths = path.Split('\\');
        StringBuilder sbNewPath = new StringBuilder(subpaths[0]);
        // Build longest sub-path that is less than MAX_PATH characters 
        for (int i = 1; i < subpaths.Length; i++)
        {
            if (sbNewPath.Length + subpaths[i].Length >= MAX_DIR_PATH)
            {
                subpaths = subpaths.Skip(i).ToArray();
                break;
            }
            sbNewPath.Append("\\" + subpaths[i]);
        }
        DirectoryInfo dir = new DirectoryInfo(sbNewPath.ToString());
        bool foundMatch = dir.Exists;
        if (foundMatch)
        {
            // Make sure that all of the subdirectories in our path exist. 
            // Skip the last entry in subpaths, since it is our filename. 
            // If we try to specify the path in dir.GetDirectories(),  
            // We get a max path length error. 
            int i = 0;
            while (i < subpaths.Length - 1 && foundMatch)
            {
                foundMatch = false;
                foreach (DirectoryInfo subDir in dir.GetDirectories())
                {
                    if (subDir.Name == subpaths[i])
                    {
                        // Move on to the next subDirectory 
                        dir = subDir;
                        foundMatch = true;
                        break;
                    }
                }
                i++;
            }
            if (foundMatch)
            {
                // Now that we've gone through all of the subpaths, see if our file exists. 
                // Once again, If we try to specify the path in dir.GetFiles(),  
                // we get a max path length error. 
                foreach (FileInfo fi in dir.GetFiles())
                {
                    if (fi.Name == subpaths[subpaths.Length - 1])
                    {
                        return fi;
                    }
                }
            }
        }
        // If we didn't find a match, return null;
        return null;
    }
    

    Now that you've seen that, go rinse your eyes and shorten your paths.

    0 讨论(0)
  • 2021-01-18 18:09

    http://www.codinghorror.com/blog/2006/11/filesystem-paths-how-long-is-too-long.html

    I recently imported some source code for a customer that exceeded the maximum path limit of 256 characters.

    The path you pasted was 285 characters long.

    As you noted in your comment, MSDN's link here (http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maximum%5Fpath%5Flength) explains this length in greater detail:

    In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string" where "" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)

    With respect to the \\?\ functionality:

    Many but not all file I/O APIs support "\?\"; you should look at the reference topic for each API to be sure.

    0 讨论(0)
  • 2021-01-18 18:18

    try with this code

    var path = Path.Combine(@"\\?\", filesToBeCopied[j]); //don't forget extension
    

    "\?\" prefix to a path string tells the Windows APIs to disable all string parsing and to send the string that follows it straight to the file system.

    Important : Not all file I/O APIs support "\?\", you should look at the reference topic for each API

    0 讨论(0)
  • 2021-01-18 18:19

    Here's a solution for at least the copying portion of your request (thank you pinvoke.net):

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    static extern bool CopyFile(string lpExistingFileName, string lpNewFileName, bool bFailIfExists);
    

    And then to actually copy your file:

    // Don't forget the '\\?\' for long paths
    string reallyLongPath = @"\\?\d:\abc\bcd\cd\cdc\dc\..........";
    string destination = @"C:\some\other\path\filename.txt";
    CopyFile(reallyLongPath , destination, false);
    
    0 讨论(0)
提交回复
热议问题