PathTooLongException C# 4.5

У меня проблемы с копированием некоторых папок с 260+ символами (например, F:\NNNNNNNNNNNNNNNN\ NNNNNNNNNNNN\ROOT\$RECYCLE.BIN\S-1-5-21-3299053755-4209892151-505108915-1000\$RMSL3UNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN NNNNNNNNNNN\NNNNNNNNNN\NNNNNNNNNN\publish\ Файлы приложений \TNNNNNNNNNNNN_1_0_0_0\NNNNNNNNNNNN.exe.manifest) в другое место со стандартным DrectoryInfo.Create); добавление \?\ или \?\UNC\ (например, "\\?\UNC\") просто вызывает другое ArgumentException. Что я делаю неправильно? Что еще я могу сделать без использования Directory.SetCurrentDirectory()?

3 ответа

Решение

Да, использование стандартных API предоставит вам такие ограничения (255 символов IIRC).

Из.NET вы можете использовать проект AlphaFS, который позволяет вам использовать очень длинные пути (используя стиль \\?\") И имитирует пространство имен System.IO.

Вы, вероятно, сможете использовать эту библиотеку так же, как если бы вы использовали System.IO, например: AlphaFS.Win32.Filesystem.File.Copy () вместо System.IO.File.Copy ()

Если вы не хотите или не можете использовать AlphaFS, вам придется пробить Win32 API

В 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 символов). Обычно вы сталкиваетесь с ошибкой System.IO.PathTooLongException со стандартной библиотекой.NET.

На самом деле вам нужно позвонить в Win32 из C#. Мы сделали это

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");
}
Другие вопросы по тегам