我无法复制某些文件夹 260+ 个字符(例如:F:\NNNNNNNNNNNNNNNN\NNNNNNNNNN\ROOT\$RECYCLE.BIN\S-1-5-21-3299053755-4209892151-505108915-1000\$RMSL3U8\NNNNNNNNN NNNNNNNN\ NNNNNNNNNNN\NNNNNNNNNN\NNNNNNNNNN\publish\Application Files\TNNNNNNNNNNNN_1_0_0_0\NNNNNNNNNNNN.exe.manifest) 使用标准 DrectoryInfo.Create(); 添加 \?\ 或 \?\UNC\(如“\\?\UNC\”)只会引发另一个 ArgumentException。我究竟做错了什么?如果不使用 Directory.SetCurrentDirectory() 我还能做什么?
3 回答
其实你需要从c#调用win32。我们已经做到了
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
public static class LongPath
{
static class Win32Native
{
[StructLayout(LayoutKind.Sequential)]
public class SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr pSecurityDescriptor;
public int bInheritHandle;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CreateDirectory(string lpPathName, SECURITY_ATTRIBUTES lpSecurityAttributes);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, SECURITY_ATTRIBUTES securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
}
public static bool CreateDirectory(string path)
{
return Win32Native.CreateDirectory(String.Concat(@"\\?\", path), null);
}
public static FileStream Open(string path, FileMode mode, FileAccess access)
{
SafeFileHandle handle = Win32Native.CreateFile(String.Concat(@"\\?\", path), (int)0x10000000, FileShare.None, null, mode, (int)0x00000080, IntPtr.Zero);
if (handle.IsInvalid)
{
throw new System.ComponentModel.Win32Exception();
}
return new FileStream(handle, access);
}
}
示例代码:
string path = @"c:\".PadRight(255, 'a');
LongPath.CreateDirectory(path);
path = String.Concat(path, @"\", "".PadRight(255, 'a'));
LongPath.CreateDirectory(path);
string filename = Path.Combine(path, "test.txt");
FileStream fs = LongPath.Open(filename, FileMode.CreateNew, FileAccess.Write);
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("abc");
}
Microsoft TechNet 上有一个很棒的库来解决长文件名问题,它叫做Delimon.Win32.IO 库 (V4.0),它有自己的 System.IO 中的关键方法版本
例如,您将替换:
System.IO.Directory.GetFiles
和
Delimon.Win32.IO.Directory.GetFiles
这将让您处理长文件和文件夹。
从网站:
Delimon.Win32.IO 取代了 System.IO 的基本文件功能,并支持多达 32,767 个字符的文件和文件夹名称。
这个库是在 .NET Framework 4.0 上编写的,可以在 x86 和 x64 系统上使用。标准 System.IO 命名空间的文件和文件夹限制可以处理文件名中包含 260 个字符和文件夹名称中包含 240 个字符的文件(MAX_PATH 通常配置为 260 个字符)。通常,您会在使用标准 .NET 库时遇到 System.IO.PathTooLongException 错误。
是的,使用标准 API 会给您这种限制(255 个字符 IIRC)。
在 .NET 中,您可以使用AlphaFS 项目,该项目允许您使用非常长的路径(使用“\\?\”样式)并模仿 System.IO 命名空间。
您可能可以像使用 System.IO 一样使用这个库,例如:AlphaFS.Win32.Filesystem。File.Copy()而不是 System.IO。文件.复制()
如果您不想或不能使用 AlphaFS,则必须调用 Win32 API