Introduction
This article shows how to delete a local file whose path exceeds the system-defined maximum length, which is always refered asLONG PATH (different from LONG FILE NAME which is used in contrast to short file names – those8.3 names).
Background
Normally, we can use File.Delete to delete a local file given the file path. However, when the file path exceeds the system-defined maximum length (say 260 characters on Windows), File.Delete will throw System.IO.PathTooLongException as shown below
[PathTooLongException]: The specified path, file name, or both are too long.
The fully qualified file name must be less than 260 characters, and the
directory name must be less than 248 characters.
What is Maximum Path Length Limitation?
In the Windows API, 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<NUL>" where "<NUL>" represents the invisible terminating null character for the current system codepage. Seehere for more details.
How come a file breaks through the Maximum Path Length Limitation?
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).
Solution
Way #1:
Instead of calling File.Delete, you can use 'del [file_name]' in Windows DOS command prompt to compulsorily delete files.
Way #2:
The Windows file APIs provide a way to get around this limitation. If you prefix the file name with "\\?\" and call the Unicode versions of the Windows APIs, then you can use file names up to 32K characters in length. In other words, the \\?\ prefix is a way to enable long paths while working with the Windows file APIs, which however, turns off file name normalization performed by Windows APIs, including removing trailing spaces, expanding ‘.’ and ‘..’, converting relative paths into full paths, and so on. With \\?\ prefix, you need to canonicalize the path as excepted and it will to a large extent raise security issues. However, this workarounds should be OK in simple cases.
Using the code (in C#)
Way #1:
static bool DeleteFile(string fileName)
{
try
{
Process cmd = new Process();
cmd.StartInfo.FileName = "del";
cmd.StartInfo.Arguments = fileName;
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.Start();
cmd.WaitForExit();
cmd.Close();
}
catch (Exception e)
{
// handle the potential exception here
}
return !File.Exists(fileName);
}
Way #2:
public static readonly string PATH_PREFIX = @"\\?\";
private static string Normalize(string pathOrFile)
{
return pathOrFile.StartsWith(PATH_PREFIX) ? pathOrFile : PATH_PREFIX + pathOrFile;
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteFile(string lpFileName);
public static bool Delete(string fileName)
{
string normalizedFileName = Normalize(fileName);
return DeleteFile(normalizedFileName);
}
More to read
- Long Paths in .NET by Kim Hamilton. Part 1 / Part 2 / Part 3
- File Management from MSDN
- Using long path syntax with UNC, MSDN
- Zeta Long Paths - a .NET library to access files and directories with more than 260 characters length.
Downloads
Download Console-based codes -1k