I am currently working on a program that traverses through various directories to ensure that specific files are present by using File.Exists()
.
The application has been claiming that certain files do not exist when they actually do, and I recently discovered that this error was due to the path being too long.
I realize there are questions on SO that address File.Exists()
returning incorrect values, but none seem to solve this particular issue.
Renaming the directories and files to shorten the path is not really an option, so I'm not sure what to do at this point. Is there a work-around that would solve this problem?
The code in use is nothing special (I've cut out some irrelevant code), but I will include it below just in case it helps.
private void checkFile(string path)
{
if (!File.Exists(path))
Console.WriteLine(" * File: " + path + " does not exist.");
}
The Exists method returns false if any error occurs while trying to determine if the specified file exists.
The file_exists() function checks whether a file or directory exists.
To test to see if a file or directory exists, use the “ exists() ” method of the Java java. io. File class. If the exists() method returns true then the file or directory does exist and otherwise does not exists.
From MSDN - Naming Files, Paths, and Namespaces:
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.
...
The Windows API has many functions that also have Unicode versions to permit an extended-length path for a maximum total path length of 32,767 characters. This type of path is composed of components separated by backslashes, each up to the value returned in the lpMaximumComponentLength parameter of the GetVolumeInformation function (this value is commonly 255 characters). To specify an extended-length path, use the
"\\?\"
prefix. For example,"\\?\D:\very long path"
....
Because you cannot use the
"\\?\"
prefix with a relative path, relative paths are always limited to a total of MAX_PATH characters.
(Emphasis added)
If all your paths are full paths, you could update your code to use the extended-length path specifier as follows:
const longPathSpecifier = @"\\?";
private void checkFile(string path)
{
// Add the long-path specifier if it's missing
string longPath = (path.StartsWith(longPathSpecifier) ? path : longPathSpecifier + path);
if (!File.Exists(longPath))
{
// Print the original path
Console.WriteLine(" * File: " + path + " does not exist.");
}
}
Update:
For file I/O, the "\?\" 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. For example, if the file system supports large paths and file names, you can exceed the MAX_PATH limits that are otherwise enforced by the Windows APIs.
At least on my system (using Windows 7), long file names are not supported, so I can't verify if the above solution will work for you.
Update: I found a solution that does work, but it is fairly ugly. Here's what I did in pseudo-code:
dir.GetDirectories()
and check if the next directory is contained in the resultsdir
to that DirectoryInfo
and keep diggingdir.GetFiles()
and see if our file exists in the returned FileInfo
objects. You need to P/Invoke Win32 APIs to get this to work properly:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern uint GetFileAttributes(string lpFileName);
public static bool DirectoryExists(string path)
{
uint attributes = GetFileAttributes(path.StartsWith(@"\\?\") ? path : @"\\?\" + path);
if (attributes != 0xFFFFFFFF)
{
return ((FileAttributes)attributes).HasFlag(FileAttributes.Directory);
}
else
{
return false;
}
}
public static bool FileExists(string path)
{
uint attributes = GetFileAttributes(path.StartsWith(@"\\?\") ? path : @"\\?\" + path);
if (attributes != 0xFFFFFFFF)
{
return !((FileAttributes)attributes).HasFlag(FileAttributes.Directory);
}
else
{
return false;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With