Каждому администратору Wintel знакома утилита Robocopy. Еще со времен Windows NT4 она вошла в Resource Kit, а начиная с Windows Vista — в состав операционной системы.
Зачем нужна Robocopy? Для того чтобы копировать файлы. Много файлов. В основном мы используем ее для миграции файловых серверов или резервного копирования.
Есть много интересных вариантов миграции файловых серверов, например, с использованием DFS-R. Но нет ничего проще и надежнее запуска

robocopy \\SERV\D$ F:\ /e /copyall /zb /mt:8 /r:1 /W:5 /V /TS /FP /ETA /TEE /LOG:c:\temp\robocopy.txt

В финале можно закрыть пользовательский доступ к ресурсу и создать инкрементальную копию, добавив ключ /MIR.
Но так ли хороша Robocopy? Хороша ли она настолько, чтобы доверить ей миграцию самых важных файлов?


Одним прекрасным субботним днем я мигрировал файловый сервер. Сотрудников на работе не оказалось. Первая копия была сделана еще вчера, оставалось лишь сделать инкремент и обновить ссылки в DFS.
Я запустил Robocopy, посмотрел журнал, а для перестраховки, перед переключением, решил посмотреть, сколько файлов и папок в исходном и конечном файловом ресурсе. Числа не сошлись. Неожиданно.

image

Но почему? Такой результат я видел впервые. Я сделал что-то не так? Кто-то из сотрудников все же изменил файлы, пока шло инкрементальное копирование? Ключ /MIR дал сбой? Какие-то файлы пропущены? Пустые? С Access Denied? Поврежденные?

Хорошо, отключаем сетевой доступ и снова копируем файлы. Не сходится! Пробуем без /MIR. Тот же результат.
Я был в недоумении. Пятнадцать лет я на 100% доверял Robocopy, и вот сегодня, впервые, она дала сбой. Некоторых файлов просто нет в месте назначения! Просто невозможно в это поверить.

Давайте подсчитаем файлы по-другому. Качаем утилиту FileList и делаем листинг файлов в исходной и конечной папке. А вот здесь число файлов совпадало. Удивительно.

А что если дело не в Robocopy? Что если Windows Explorer считает неправильно? Может быть в Windows Server 2008 R2 плохой Explorer, а в Windows Server 2012 R2 хороший? Я открыл свойства локальной и целевой папки на исходном сервере Windows Server 2008 R2. Число файлов не совпадало. Понадеемся, что в Windows Server 2012 R2 все исправлено. Открываем свойства папок на новом сервере… И…



Не совпало не только число файлов в исходной и конечной папке. Число файлов отличалось от снятых на Windows Server 2008 R2. Черная уличная магия.

И в эту минуту (наконец-то) на меня снизошло прозрение. Дело не в Robocopy, и не в версиях Explorer. Просто Explorer не умеет (!) считать, и не считает файлы и папки с именами длиннее 260 символов.

На исходном сервере файлы были расположены по пути «F:\Office1». На новом — «U:\SharedFiles\Office1».
Всего лишь из-за подпапки «SharedFiles» имена некоторых файлов и папок стали длиннее 255 символов. Для Robocopy не составило труда их скопировать. FileList легко их подсчитал. И только Explorer пропустил такие файлы при подсчете.

Сделав subst N: U:\SharedFiles и посчитав число файлов в F:\Office1 на исходном сервере и N:\Office1 на целевом, число файлов совпало.

@#$!!!

Robocopy можно доверять.

UPD: Как правильно поправляют в комментариях, все же не 255, а 260 символов.
256 — непосредственно имя файла «file.txt»
3 — «C:\»
1 — невидимый null в конце
Спасибо!

Комментарии (13)


  1. Botkin
    29.06.2015 11:59
    +6

    Когда ж они научат explorer-то работать с длинными путями. С sharepoint и onedrive из-за этого имеем целую кучу неприятностей


    1. gotch Автор
      29.06.2015 12:40
      +1

      Добавим — когда они научат Powershell работать с длинными путями. Вот еще один источник головной боли.

      Что это, господа? gallery.technet.microsoft.com/scriptcenter/Function-to-get-file-and-475aeb3a
      Обертка для Powershell с использованием Robocopy.


    1. bougakov
      29.06.2015 17:29
      +2

      никогда, потому что поддерживают совместимость
      с древними временами, когда MAX_PATH был выставлен в 260 символов.

      Ставьте перед путём префикс \\?\ и будет вам счастье — тот же Explorer будет обрабатывать пути хоть по 30 тыс. символов длиной.


      1. gotch Автор
        29.06.2015 18:37

        Ошибся веткой. В Powershell Get-ChildItem не принимает префикс, поэтому практическая польза от него довольно условная. Explorer тоже не заставишь работать с «длинными» именами, кроме как сделав subst.


      1. andreishe
        29.06.2015 20:40
        +2

        Проблема с длинными путями в Windows несколько глубже, чем кажется, и просто так, префиксами, не решается.


  1. gotch Автор
    29.06.2015 18:32
    +2

    Да вот если бы из этого тайного знания можно было бы извлечь практическую пользу.

    PS C:\Users\Michael> Get-ChildItem \\.\c:\temp
    Get-ChildItem : Данный формат пути не поддерживается.
    
    


    PS C:\Users\Michael> Get-ChildItem \\?\c:\temp
    Get-ChildItem : Путь содержит недопустимые знаки.
    


    PS C:\Users\Michael> Get-ChildItem c:\temp
    Get-ChildItem : Слишком длинный путь или имя файла. Полное имя файла должно содержать меньше 260 знаков,
    


  1. calx
    30.06.2015 10:05
    +2

    У нас были большие проблемы с robocopy, в результате чего мы пришли к обратному выводу. Он молча пропускал файлы с проблемами в кодировке имени. Как такие файлы у нас образовались, это другой вопрос, но факт остаётся фактом. В итоге написали утилиту копирования на JScript. И смех и грех.


    1. gotch Автор
      30.06.2015 14:53

      Интересно, включал ли он их в журнал как пропущенные?


      1. calx
        30.06.2015 15:07

        Нет, он нигде их не показывал, и вообще внешне всё выглядело нормально.


        1. gotch Автор
          30.06.2015 18:50

          Это не очень хорошо. Спасибо, буду иметь в виду, может и встретится.


  1. calx
    30.06.2015 15:05

    (ошибся веткой)


  1. MrShoor
    01.07.2015 03:14
    +1

    Только не 255 а 260:
    msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
    Более того Explorer не даст вам создать такой файл. Я думаю это сделано специально для обратной совместимости, чтобы после работы с файлами в Explorer вы по прежнему могли открыть его во всех старых программах.
    Ну а почему неправильно считает — это отдельный вопрос.


    1. gotch Автор
      01.07.2015 12:32

      Да, вы правы, чуть выше тоже подметили это упущение. Спасибо.