简体   繁体   中英

Error: File Path is Too Long

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 windows 7 ie 260. Its giving me an error on long path name. On MSDN support i they have asked to use the \\\\?\\ before the path. I did the same but still i got the same error, it seems it doesn't make any change. Below is my code. Please let me know if i am using it correct or i need to add any thing:
These all lib i am using as the code is having other things also:

the below is the respective code:

filesToBeCopied = Directory.GetFiles(path,"*",SearchOption.AllDirectories);
for (int j = 0; j < filesToBeCopied.Length; j++)
{
    try
    {
        String filepath = @"\\?\" + filesToBeCopied[j];
        File.GetLastWriteTime(filepath);
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error Inside the single file iteration for the path:" +
            filesToBeCopied[j] + " . The exception is :" + ex.Message);
    }
}

where as path is the path to the folder at windows machine starting with drive letter. for ex.: d:\\abc\\bcd\\cd\\cdc\\dc\\..........

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);

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM