tags:

views:

90

answers:

3

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

+2  A: 

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

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

codekaizen
This did the trick, Although it did require using VS 2010 and framework 4.
J Edward Ellis
Also, the Long Path library doesn't properly support UNC paths.
J Edward Ellis
Ugh. At least there is an outstanding issue with a good number of votes: http://bcl.codeplex.com/workitem/7589
codekaizen
A: 

Hi J,

I had a similar problem. I ended up mapping drives. You can see my solution here.

http://stackoverflow.com/questions/2450604/how-do-i-get-the-security-details-for-a-long-path

Biff MaGriff
+1  A: 

Windows does support paths longer than 260 however this functionality is not exposed through .Net directly. To get the length of 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 paths upto 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); 
}

}
Bear Monkey