Как заставить Robocopy перезаписывать файлы?

В общем, Robocopy игнорирует файлы, для которых lastwrittendate и размер файла совпадают. Как мы можем избежать этого дизайна? Я хотел бы принудительно перезаписать с Robocopy.

Я ожидал, что dst\sample.txt должен быть написан test001. Но эти файлы распознаются Robocopy как одни и те же файлы и не перезаписываются. Опция "/IS" в этом случае не действует.

New-Item src -itemType Directory
New-Item dst -itemType Directory
New-Item src\sample.txt -itemType File -Value "test001"
New-Item dst\sample.txt -itemType File -Value "test002"
Set-ItemProperty src\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"
Set-ItemProperty dst\sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00"

ROBOCOPY.exe src dst /COPYALL /MIR
Get-Content src\sample.txt, dst\sample.txt
> test001
> test002

ROBOCOPY.exe src dst /COPYALL /MIR /IS
Get-Content src\sample.txt, dst\sample.txt
> test001
> test002

2 ответа

Из документации:

/is Включает в себя те же файлы.
/it Включает "подправленные" файлы.

"Одни и те же файлы" означают файлы, которые идентичны (имя, размер, время, атрибуты). "Настроенные файлы" означают файлы, которые имеют одинаковое имя, размер и время, но разные атрибуты.

robocopy src dst sample.txt /is      # copy if attributes are equal
robocopy src dst sample.txt /it      # copy if attributes differ
robocopy src dst sample.txt /is /it  # copy irrespective of attributes

Этот ответ на SuperUser имеет хорошее объяснение того, какие файлы соответствуют параметрам выбора.

С учетом сказанного я мог бы воспроизвести описанное вами поведение, но исходя из моего понимания документации и результатов robocopy генерируется в моих тестах, я бы посчитал это ошибкой.

PS C: \ temp> Каталог нового типа src -Type> $ null PS C: \ temp> Каталог нового типа dst -Type> $ null PS C: \ temp> New-Item src \ sample.txt -Тип файла - Значение "test001"> $ null PS C: \ temp> New-Item dst \ sample.txt -Тип файла -Значение "test002"> $ null PS C: \ temp> Set-ItemProperty src \ sample.txt -Name LastWriteTime - Значение "2016/1/1 15:00:00" PS C: \ temp> Set-ItemProperty dst \ sample.txt -Name LastWriteTime -Value "2016/1/1 15:00:00" PS C: \ temp> robocopy src dst sample.txt / is / it / copyall / mir... Параметры: /S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 / Вт: 30 --------- -------------------------------------------------- ------------------- 1 C: \ temp \ src \ Modified 7 sample.txt ------------------ -------------------------------------------------- ---------- Всего скопированных пропущенных несоответствий FAILED Дополнительные файлы Dirs:         1         0         0         0         0         0 Файлы: 1 1 0 0 0 0 Байт: 7 7 0 0 0 0...
PS C:\temp> robocopy src dst sample.txt / is / it / copyall / mir... Параметры: /S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 / Вт: 30 ---------- ------------ -------------------------------------------------- ------ 1 C: \ temp \ src \ Same 7 sample.txt ------------------------------- ----------------------------------------------- Всего скопировано пропущено Несоответствие FAILED Доп. Каталоги: 1 0 0 0 0 0 Файлы: 1 1 0 0 0 0 Байт: 7 7 0 0 0 0...
PS C:\temp> Get-Content. \ Src \ sample.txt test001 PS C: \ temp> Get-Content. \ dst \ sample.txt test002 

Файл указан как скопированный, и так как он становится тем же файлом после первого robocopy запустить хотя бы раз синхронизируются. Однако, несмотря на то, что в соответствии с выводом было скопировано 7 байтов, в обоих случаях данные фактически не записывались в целевой файл, несмотря на установленный флаг данных (через /copyall). Поведение также не меняется, если флаг данных установлен явно (/copy:d).

Мне пришлось изменить время последней записи, чтобы получить robocopy на самом деле синхронизировать данные.

 PS C: \ temp> Set-ItemProperty src \ sample.txt -Name LastWriteTime -Value (Get-Date)
PS C: \ temp> robocopy src dst sample.txt / is / it / copyall / mir...
  Опции: /S /E /COPYALL /PURGE /MIR /IS /IT /R:1000000 / Вт: 30

-------------------------------------------------- ----------------------------

                           1 C: \ temp \ src \
100% новее 7 sample.txt

-------------------------------------------------- ----------------------------

               Всего скопированных пропущенных несоответствий FAILED
    Dirs:         1         0         0         0         0         0
   Файлы: 1 1 0 0 0 0
   Байт: 7 7 0 0 0 0...
PS C: \ temp> Get-Content. \ Dst \ sample.txt
test001 

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

& robocopy src dst /is /it /l /ndl /njh /njs /ns /nc |
  Where-Object { $_.Trim() } |
  ForEach-Object {
    $f = Get-Item $_
    $f.LastWriteTime = $f.LastWriteTime.AddSeconds(1)
  }
& robocopy src dst /copyall /mir

Переключение на xcopy вероятно, ваш лучший вариант:

& xcopy src dst /k/r/e/i/s/c/h/f/o/x/y

Это действительно странно, почему никто не упоминает переключатель /IM?! Давно использую в резервных работах. Но я только что попробовал поискать в Google, и мне не удалось найти ни одной веб-страницы, которая хоть что-то говорит об этом даже на сайте MS!!! Также было найдено так много сообщений пользователей с жалобами на ту же проблему!!

В любом случае... чтобы использовать Robocopy для перезаписи ВСЕГО, независимо от размера или времени в источнике или расстоянии, вы должны включить эти три переключателя в свою команду (/IS /IT /IM)

/IS :: Include Same files. (Includes same size files)
/IT :: Include Tweaked files. (Includes same files with different Attributes)
/IM :: Include Modified files (Includes same files with different times).

Это точная команда, которую я использую для передачи нескольких терабайт файлов размером более 1 ГБ (ISO - образы дисков - видео 4K):

robocopy B:\Source D:\Destination /E /J /COPYALL /MT:1 /DCOPY:DATE /IS /IT /IM /X /V /NP /LOG:A:\ROBOCOPY.LOG

Я сделал для вас небольшой тест... и вот результат:

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :      1028      1028         0         0         0       169
   Files :      8053      8053         0         0         0         1
   Bytes : 649.666 g 649.666 g         0         0         0   1.707 g
   Times :   2:46:53   0:41:43                       0:00:00   0:41:44


   Speed :           278653398 Bytes/sec.
   Speed :           15944.675 MegaBytes/min.
   Ended : Friday, August 21, 2020 7:34:33 AM

Dest, Disk: WD Gold 6TB (сравните скорость записи с моим результатом)

Даже с этими "Extras", это для отчетов только из-за переключателя "/X". Как видите, ничего не было пропущено, а общее количество и размер всех файлов равны количеству скопированных. Иногда он показывает небольшое количество пропущенных файлов, когда я злоупотребляю им, и отменяю его несколько раз во время работы, но даже при этом значения в первых двух столбцах всегда равны. Я также подтвердил это однажды, запустив сценарий PowerShell, который сканирует все файлы в месте назначения и генерирует отчет со всеми отметками времени.

Несколько советов по производительности из моей истории с ним, а также множества тестов и проблем!:

. Несмотря на то, что большинство пользователей в сети советуют использовать максимальное количество потоков "/MT:128", как будто это общий трюк для достижения максимальной производительности... ПОЖАЛУЙСТА, НЕ ИСПОЛЬЗУЙТЕ "/MT:128" С ОЧЕНЬ БОЛЬШИМИ ФАЙЛАМИ... это большая ошибка, и это резко снизит производительность вашего диска после нескольких запусков... это вызовет очень высокую фрагментацию или даже приведет к сбою файловой системы в некоторых случаях, и вы в конечном итоге потратите драгоценное время на попытки восстановить раздел RAW и всю эту ерунду. И, кроме того, он будет работать в 4-6 раз медленнее!!

Для очень больших файлов:

  1. Использовать только "одну" резьбу "/MT:1" | Воздействие: БОЛЬШОЕ
  2. Необходимо использовать "/J" для отключения буферизации. | Воздействие: высокое
  3. Используйте "/NP" с "/LOG:file" и не выводите на консоль с помощью "/TEE" | Воздействие: среднее.
  4. Поместите "/LOG:file" на отдельный диск от источника или назначения | Воздействие: низкое.

Для обычных больших файлов:

  1. Используйте многопоточность, я бы не превышал "/MT:4" | Воздействие: БОЛЬШОЕ
  2. ЕСЛИ на целевом диске мало кеша, используйте "/J" для отключения буферизации | Воздействие: высокое
  3. & 4 то же, что и выше.

Для тысяч крошечных файлов:

  1. Сходи с ума:) с многопоточностью, сначала я бы начал с 16 и умножить на 2, отслеживая производительность диска. Как только оно начнет падать, я вернусь к предыдущему значению и буду использовать его | Воздействие: БОЛЬШОЕ
  2. Не используйте "/J" | Воздействие: высокое
  3. Используйте "/NP" с "/LOG:file" и не выводите на консоль с помощью "/TEE" | Воздействие: ВЫСОКОЕ.
  4. Поместите "/LOG:file" на отдельный диск от источника или назначения | Воздействие: ВЫСОКОЕ.

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

FOR /F "tokens=*" %G IN ('dir /b') DO robocopy  "\\server02\Folder with shortcut" "\\server02\home\%G\Desktop" /S /A /V /log+:C:\RobocopyShortcut.txt /XF *.url *.mp3 *.hta *.htm *.mht *.js *.IE5 *.css *.temp *.html *.svg *.ocx *.3gp *.opus *.zzzzz *.avi *.bin *.cab *.mp4 *.mov *.mkv *.flv *.tiff *.tif *.asf *.webm *.exe *.dll *.dl_ *.oc_ *.ex_ *.sy_ *.sys *.msi *.inf *.ini *.bmp *.png *.gif *.jpeg *.jpg *.mpg *.db *.wav *.wma *.wmv *.mpeg *.tmp *.old *.vbs *.log *.bat *.cmd *.zip /SEC /IT /ZB /R:0

Как вы видите, существует множество типов файлов, которые я настроил игнорировать (на всякий случай), просто установите их для своих нужд или вашего сценария.

Протестировано на сервере 2012, каждый переключатель документирован на сайтах Microsoft и других.

Другие вопросы по тегам