简体   繁体   中英

How do I get the length of a file with a path longer than 260 characters?

I am trying to find especially large files on a file share with deeply nested folders. They aren't my folders, so I don't get to rearrange them. The usual way to get the length of a file is:

string fullPath = "C:\path\file.ext";
FileInfo info = new FileInfo(fullPath);
long len = info.Length;

If the length of the path is greater than 260 characters, the FileInfo constructor throws a PathTooLongException. I've read the Kim Hamilton blog entries on long file paths in .NET, so I know it can be done if I ditch the framework and do it all with Win32 API calls. Is there a way to do it with the framework?

Kim Hamilton blog entries on long file paths in .NET:
Part 1
Part 2
Part 3

Check out the BCL Codeplex site, they have a future extension which might help you now:

http://bcl.codeplex.com/wikipage?title=Long%20Path

Windows does support paths longer than 260. However, this functionality is not exposed through .NET directly. To get the length of a file with path longer than 260, use the GetFileAttributesEx Windows API function which can be accessed in .NET through marshalling:

[StructLayout(LayoutKind.Sequential)]
public struct WIN32_FILE_ATTRIBUTE_DATA
{
    public FileAttributes dwFileAttributes;
    public FILETIME ftCreationTime;
    public FILETIME ftLastAccessTime;
    public FILETIME ftLastWriteTime;
    public uint nFileSizeHigh;
    public uint nFileSizeLow;
}

public enum GET_FILEEX_INFO_LEVELS {
    GetFileExInfoStandard,
    GetFileExMaxInfoLevel
}

public class MyClass
{
    [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
    private static extern bool GetFileAttributesEx(string lpFileName,
          GET_FILEEX_INFO_LEVELS fInfoLevelId, out WIN32_FILE_ATTRIBUTE_DATA fileData);

    public static long GetFileLength(string path)
    {
         // Check path here

         WIN32_FILE_ATTRIBUTE_DATA fileData;

         // Append special suffix \\?\ to allow path lengths up to 32767
         path = "\\\\?\\" + path;

         if(!GetFileAttributesEx(path,
                 GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, out fileData))
         {
               throw new Win32Exception();
         }
         return (long)(((ulong)fileData.nFileSizeHigh << 32) +
                        (ulong)fileData.nFileSizeLow);
    }
}

试用 Zeta Long Paths 库:http: //zetalongpaths.codeplex.com/

Works with the Microsoft Scripting Runtime COM reference

var fso = new Scripting.FileSystemObject();
double fileSize = fso.GetFile(path).Size;  // path is over 300 chars

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