Get the size of files having long path in C#.Net 3.5
Suppose you
want to get the size of all the files present in a directory. You would do
something like this:
Method 1:
DirectoryInfo di = new
DirectoryInfo(path); // path: It’s the path
to the directory
FileInfo[] fInfos = di.GetFiles();
long fileSize = 0;
foreach (FileInfo fi in fInfos)
{
fileSize = fi.Length;
}
But if you have files having full path (including directory name) more
than 260 characters, “fi.Length” will throw FileNotFoundException. Even if the file
exists, you will get this error, as shown in the screenshot below:
To fix this
issue, include the following namespace:
using System.Reflection;
And use the below
code:
public const int MAX_PATH = 260;
public const int MAX_ALTERNATE = 14;
[StructLayout(LayoutKind.Sequential)]
public struct FILETIME
{
public uint dwLowDateTime;};
public uint dwHighDateTime;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WIN32_FIND_DATA
{
public FileAttributes dwFileAttributes;}
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ALTERNATE)]
public string cAlternate;
[DllImport("kernel32", CharSet = CharSet.Unicode)]public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
Define the
below function that will return the size of files having long path:
private long getFileSize(string fileName, out WIN32_FIND_DATA findData)
{
long size = 0;
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
IntPtr findHandle;
findHandle = FindFirstFile(@"\\?\"
+ fileName , out findData);
if (findHandle != INVALID_HANDLE_VALUE)
{
if ((findData.dwFileAttributes & FileAttributes.Directory) == 0)
{
size = (long)findData.nFileSizeLow + (long)findData.nFileSizeHigh * 4294967296;
}
}
return size;
}
Update the
Method 1 with the below code:
DirectoryInfo di = new DirectoryInfo(path); // path: It’s the path to the directory
FileInfo[] fInfos = di.GetFiles();
long fileSize = 0;
if (fi.Exists)
{
fileSize = fi.Length;}
else
{
// This will handle long paths}
FieldInfo fld = typeof(FileSystemInfo).GetField( "FullPath", BindingFlags.Instance |
BindingFlags.NonPublic);
string fullPath = fld.GetValue(fi).ToString();
WIN32_FIND_DATA findData;
fileSize = getFileSize(fullPath, out findData);
The function
getFileSize
outputs “findData” of type WIN32_FIND_DATA. It can be used to get the attribute,
created date, last access date and other properties of file having long path as
below:
string attribute = findData.dwFileAttributes.ToString();
DateTime CreationTime = DateTime.FromFileTimeUtc((((long)findData.ftCreationTime.dwHighDateTime) <<
32) | ((uint)findData.ftCreationTime.dwLowDateTime));
DateTime LastAccessTime = DateTime.FromFileTimeUtc((((long)findData.ftLastAccessTime.dwHighDateTime)
<< 32) | ((uint)findData.ftLastAccessTime.dwLowDateTime));
DateTime LastWriteTime = DateTime.FromFileTimeUtc((((long)findData.ftLastWriteTime.dwHighDateTime)
<< 32) | ((uint)findData.ftLastWriteTime.dwLowDateTime));
No comments:
Post a Comment