Как заставить 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 раз медленнее!!
Для очень больших файлов:
- Использовать только "одну" резьбу "/MT:1" | Воздействие: БОЛЬШОЕ
- Необходимо использовать "/J" для отключения буферизации. | Воздействие: высокое
- Используйте "/NP" с "/LOG:file" и не выводите на консоль с помощью "/TEE" | Воздействие: среднее.
- Поместите "/LOG:file" на отдельный диск от источника или назначения | Воздействие: низкое.
Для обычных больших файлов:
- Используйте многопоточность, я бы не превышал "/MT:4" | Воздействие: БОЛЬШОЕ
- ЕСЛИ на целевом диске мало кеша, используйте "/J" для отключения буферизации | Воздействие: высокое
- & 4 то же, что и выше.
Для тысяч крошечных файлов:
- Сходи с ума:) с многопоточностью, сначала я бы начал с 16 и умножить на 2, отслеживая производительность диска. Как только оно начнет падать, я вернусь к предыдущему значению и буду использовать его | Воздействие: БОЛЬШОЕ
- Не используйте "/J" | Воздействие: высокое
- Используйте "/NP" с "/LOG:file" и не выводите на консоль с помощью "/TEE" | Воздействие: ВЫСОКОЕ.
- Поместите "/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 и других.