Вопрос

ФОН

Мне нужно написать инструмент, использующий .NET версии максимум 2.0 (использование чего-то готового для этого клиента не является вариантом по политическим, коммерческим причинам, а также по соображениям конфиденциальности/доверия) для переноса файлов с одного сервера на другой по сети.Серверы являются файловыми серверами для локальных групп, и некоторые папки группы необходимо перенести на другие серверы, чтобы облегчить реорганизацию.Основная идея заключается в том, что мы читаем каждый файл и передаем его по сети в нерабочее время, а через несколько дней данные будут перенесены.Права доступа к файлам должны быть сохранены.Поскольку это займет несколько дней (для некоторых команд речь идет о нескольких гигабайтах данных), нам нужно каждую ночь перебирать файлы, сравнивать даты модификации и обновлять те, которые изменились.Теория состоит в том, что в конечном итоге на новом сервере появится обновленная копия файлов, и пользователи смогут переключиться на новый сервер.Это, конечно, не так просто, но у нас есть дизайн, который, по нашему мнению, должен работать :)

ПРОБЛЕМА

То есть теоретически мы просто открываем файл, передаем его по сети и записываем на другом конце, верно?:)

К сожалению, на самих серверах общие файловые ресурсы были созданы по таким путям к папкам, как:

D:\Data eam Shares\DIVISION\DEPARTMENT\ИМЯ КОМАНДЫ - МОЖЕТ БЫТЬ ДОВОЛЬНО ДЛИННЫМ\

Для каждого пользователя этот путь сопоставляется с диском, например, он будет доступен как \\SERVER EAMNAME и сопоставлен с буквой T:водить машину.

Это привело к ситуации, когда файлы, видимые с помощью T:привод находятся в пределах MAX_PATH ограничение, однако при локальном просмотре на самом сервере они выходят далеко за его пределы.Мы не можем получить доступ к файлам, используя общие сетевые ресурсы, поскольку этот инструмент должен быть универсальным, чтобы работать на сотнях этих серверов, и не существует стандартного способа определить, какие общие файловые ресурсы нам следует перемещать, а какие нет. нет даже стандарта соглашения об именах.Кроме того, иногда появляются дополнительные акции других акций, и поэтому мы превышаем MAX_PATH лимит превышен в два раза!

Мне известен обходной путь для указания путей с использованием префикса «\\?\", который рассматривает путь как путь UNC и допускает теоретический максимум 32 тыс. символов.

Этот обходной путь реализован на уровне API Win32, пространство имен System.IO (в основном) представляет собой просто тонкую оболочку собственных функций API Win32, однако Microsoft «услужливо» реализовала дополнительную (неправильную) проверку перед передачей вызова API. .В этом случае .NET Framework отклоняет путь, потому что он утверждает, что "?" является неверным персонажем пути.

Итак, мой вопрос...есть ли способ, о котором я не думал, который позволит мне обойти это без необходимости полностью переписывать почти все пространство имен System.IO, выполняя нагрузку вызовов P/Invoke, просто чтобы удалить эту раздражающую проверку?

Это было полезно?

Решение

Команда BCL подготовила серию из трех статей о том, почему был сделан такой выбор и каковы обходные пути.Если вы еще не прочитали это, я советую вам это сделать, поскольку это отличный источник информации по этому вопросу.

Другие советы

Я столкнулся с одним сторонним решением, которое может помочь: АльфаФС.

Это ограничение должно быть довольно легко обойти с помощью небольшого вызова платформы, при условии, что ваше программное обеспечение имеет необходимые разрешения:

[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
  uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
  uint dwFlagsAndAttributes, IntPtr hTemplateFile);

// Must close/dispose handle separately from FileStream since it's not owned by
// that object when passed to constructor.
using (SafeFileHandle h = CreateFile(longUncPath, GENERIC_WRITE, 0, IntPtr.Zero, 
       OPEN_EXISTING, 0, IntPtr.Zero))
{
    using (var fs = new FileStream(h, FileAccess.Read))
    {
        // operations with FileStream object
    }
}

Вы можете попробовать сократить путь, сопоставив родительский каталог с помощью subst.exe (или любого другого API, который он использует внутри):

http://www.makeuseof.com/tag/how-to-map-a-local-windows-folder-to-a-drive-letter/

В идеале вы должны нанести на карту как можно большую часть пути.

Мне удалось удалить структуры каталогов, используя небольшой скрипт ниже.pushd использует формат UNC, который дает ограничение в 32 КБ вместо 260.

set "folder=\\SERVER\SHARE\DIVISION\DEPARTMENT\NAME OF TEAM - COULD BE FAIRLY LONG\" 
pushd "%folder%"
for /d %%i in ("*") do rmdir "%%i" /s /q
popd
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top