5

我无法复制某些文件夹 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() 我还能做什么?

4

3 回答 3

8

其实你需要从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");
}
于 2012-10-05T13:31:58.913 回答
8

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 错误。

于 2013-02-16T06:01:34.367 回答
5

是的,使用标准 API 会给您这种限制(255 个字符 IIRC)。

在 .NET 中,您可以使用AlphaFS 项目,该项目允许您使用非常长的路径(使用“\\?\”样式)并模仿 System.IO 命名空间。

您可能可以像使用 System.IO 一样使用这个库,例如:AlphaFS.Win32.Filesystem。File.Copy()而不是 System.IO。文件.复制()

如果您不想或不能使用 AlphaFS,则必须调用 Win32 API

于 2012-10-05T13:23:18.527 回答