【问题标题】:PathTooLongException C# 4.5PathTooLongException C# 4.5
【发布时间】:2012-09-26 15:53:01
【问题描述】:

我无法复制某些文件夹 260 多个字符(例如:F:\NNNNNNNNNNNNNNNN\NNNNNNNNNNNN\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() 我还能做什么?

【问题讨论】:

标签: c# exception visual-studio-2012 io pathtoolongexception


【解决方案1】:

Microsoft TechNet 上有一个很棒的库来解决长文件名问题,它被称为 Delimon.Win32.I​O Library (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 错误。

【讨论】:

  • Delimon 很棒,我用了一段时间了,但它不支持 FileStream。正如 Vinoth 所说,最好从 C# 调用 Win32。
【解决方案2】:

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

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

您可能可以像使用 System.IO 一样使用此库,例如:AlphaFS.Win32.Filesystem.File.Copy() 而不是 System.IO.File.Copy()

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

【讨论】:

  • 英文和体验问题。什么是“必须 ****pinvoke Win32**** API”?
  • 我的意思是“调用原生 Windows API C/c++ 函数”,使用 .Net 语言中称为 p/invoke 的东西。
  • 如果你暂时缺乏经验,我建议你试试AlphaFS,它会容易得多。
  • 好吧,现在它是关于 Stackoverflow 上那个问题的最好最简单的答案,干得好! :D
  • 谢谢!如果您不想要 AlphaFS 而更喜欢“p/invoking”,请查看下面 Vinoth 的精彩回答。
【解决方案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");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    相关资源
    最近更新 更多