[Tech Note] Delete files with long path

来源:互联网 发布:程序员客栈怎么接单 编辑:程序博客网 时间:2024/05/18 13:45

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 fromLONG 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 exceed​s 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



0 0
原创粉丝点击