Альтернатива Directory.CreateDirectory(path), поддерживающая длинные пути
Просто интересно, есть ли альтернатива Directory.CreateDirectory()
я пытаюсь создать каталог длиной более 260 символов, хотя имя файла не длинное, а путь к каталогу.
ИЛИ ЖЕ
Если есть какой-то трюк, используя который я могу указать CreateDirectory
создать папку в этом месте без указания полного пути к каталогу. Поскольку я создаю папки внутри папок и так далее. Должен быть какой-то законный способ сделать это.
Возникла проблема со строкой, которую я сейчас сохранил в скрытом ярлыке, так что это больше не проблема.
4 ответа
Простое решение состоит в том, чтобы использовать unc-включенный путь, который будет позволять пути к файлам приблизительно до 32767 символов
string longPathEnabledFileName = Path.ToLongPath("C:\SomeVeryLongPath\....");
FileStream fs = new FileStream(longPathEnabledFileName);
Это просто добавит путь к \\?\, Что говорит каркасу обойти ограничение MAX_PATH в 260 символов. К сожалению, префикс \\?\ Не поддерживается в.Net на момент написания (начиная с версии 4.0)
Это оставляет нам решение WinApi и ссылку Kernel32.dll на использование SafeFileHandle. Ким Хэмилтон из команды BCL опубликовал здесь серию обходных путей к ограничениям MAX_PATH (часть 2 показывает, как использовать функции winapi) с фрагментом кода, включенным здесь для справки:
// Этот фрагмент кода предоставляется в рамках разрешающей лицензии Microsoft. используя Систему; используя System.IO; using System.Runtime.InteropServices; использование Microsoft.Win32.SafeHandles; [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] внутренний статический extern SafeFileHandle CreateFile(строка lpFileName, EFileAccess dwDesiredAccess, EFileShare dwShareMode, IntPtr lpSecurityAttributes, ECreationDisposition dwCreationDisposition, EFileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile); public static void TestCreateAndWrite(строка fileName) { string formattedName = @"\\?\" + fileName; // Создать файл с общим доступом для записи SafeFileHandle fileHandle = CreateFile(formattedName, EFileAccess.GenericWrite, EFileShare.None, IntPtr.Zero, ECreationDisposition.CreateAlways, 0, IntPtr.Zero); // Проверка на ошибки int lastWin32Error = Marshal.GetLastWin32Error(); if (fileHandle.IsInvalid) { бросить новый System.ComponentModel.Win32Exception(lastWin32Error); } // Передаем дескриптор файла в FileStream. FileStream закроет // справиться используя (FileStream fs = new FileStream (fileHandle, FileAccess.Write)) { fs.WriteByte (80); fs.WriteByte (81); fs.WriteByte (83); fs.WriteByte (84); } }
Существует также библиотека, которая инкапсулирует всю эту работу в коде Google, которая называется "Зета длинные пути".
Установите каталог как текущий и создайте каталог в нем.
Directory.SetCurrentDirectory(@"c:\sample");
Directory.CreateDirectory("test");
Альтернативный способ - использование DirectoryInfo
класс и метод DirectoryInfo.Create
,
Я не пробовал, но MSDN показывает, что это не исключение, если вы используете слишком длинный путь.
РЕДАКТИРОВАТЬ:
Также я нашел кое-что, что может помочь вам решить вашу проблему. Посмотрите на этот код
Как насчет разделения вашего предполагаемого пути с помощью символа '\', затем циклически проходя по каждому элементу, проверяя, существует ли каталог, если нет - создайте его, а затем используйте
Directory.SetCurrentDirectory(directoryName);