1

После того, как мой жесткий диск дал мне ошибки CRC, я захотел скопировать один диск на другой и взял новый жесткий диск емкостью 1 ТБ.

Я использую команду:

robocopy G: J: /MIR /COPYALL /ZB

Сначала он попытался скопировать файл несколько раз (я не считал, его больше нет в моем окне) и получил ошибку отказа в доступе, ошибка 5. Затем он попробовал еще раз и заперся. Я попытался скопировать этот конкретный файл (14 МБ), и Windows говорит: «Не могу прочитать из исходного файла или с диска».

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

Я открыт для других решений копирования. Я предпочитаю встроенные решения. Я использую Windows 7.

Кроме того, как я могу сделать это без параметра /MIR ? Достаточно ли хорош /S /E ? пометить ссылку здесь

Я вижу, что могу контролировать повторные попытки с помощью /R:<Amount>, но я все еще открыт для альтернативных решений.

Кажется, пройдет несколько минут, прежде чем он решит, что попытка не удалась. Могу ли я сократить его? Файл временно застрял на 20,8%.

Я попробовал приложение для восстановления данных. Он попытался восстановить данные и НЕ пометил их как недействительные или поврежденные. Хотя я получил сообщение о том, что в секторе XYZ произошла ошибка ввода-вывода, продолжить? но это не дало мне имя поврежденного файла. Я не хочу этого Лучшее решение для меня - это получить все хорошие файлы + имена неверных файлов.

4 ответа4

2

Я написал небольшой скрипт PowerShell, чтобы игнорировать ошибки ввода-вывода устройства при копировании (и, таким образом, заменить нечитаемые данные нулями). Обновленная и более продвинутая версия доступна здесь. Код, который я разместил здесь, является одной из первых версий и настолько прост, насколько это возможно:

## .SYNOPSIS
#########################
## This script copies a file, ignoring device I/O errors that abort the reading of files in most applications.
##
## .DESCRIPTION
#########################
## This script will copy the specified file even if it contains unreadable blocks caused by device I/O errors and such. The block that it can not read will be replaced with zeros. The size of the block is determined by the buffer. So, to optimize it for speed, use a large buffer. T optimize for accuracy, use small buffer, smallest being the cluster size of the partition where your source file resides.
##
## .OUTPUTS
#########################
## Errorcode 0: Copy operation finished without errors.
##
## .INPUTS
#########################
## Blabla..
##
## .PARAMETER SourceFilePath
## Path to the source file.
##
## .PARAMETER DestinationFilePath
## Path to the destination file.
##
## .PARAMETER Buffer
## I makes absolutely no sense to set this less than the cluster size of the partition. Setting it lower than cluster size might force rereading a bad sector in a cluster multiple times. Better is to adjust the retry option. Also, System.IO.FileStream buffers input and output for better performance. (http://msdn.microsoft.com/en-us/library/system.io.filestream.aspx).
##
## .EXAMPLE
## .\Force-Copy.ps1 -SourceFilePath "file_path_on_bad_disk" -DestinationFilePath "destinaton_path"
##
#########################

[CmdletBinding()]
param(
   [Parameter(Mandatory=$true,
              ValueFromPipeline=$true,
              HelpMessage="Source file path.")]
   [string][ValidateScript({Test-Path -LiteralPath $_ -Type Leaf})]$SourceFilePath,
   [Parameter(Mandatory=$true,
              ValueFromPipeline=$true,
              HelpMessage="Destination file path.")]
   [string][ValidateScript({ -not (Test-Path -LiteralPath $_) })]$DestinationFilePath,
   [Parameter(Mandatory=$false,
              ValueFromPipeline=$false,
              HelpMessage="Buffer size in bytes.")]
   [int32]$BufferSize=512*2*2*2 # 4096: the default windows cluster size.
)

Write-Host "Working..." -ForegroundColor "Green";

# Making buffer
$Buffer = New-Object System.Byte[] ($BufferSize);
$UnreadableBits = 0;

# Fetching source and destination files.
$SourceFile = Get-Item -LiteralPath $SourceFilePath;
$DestinationFile = New-Object System.IO.FileInfo ($DestinationFilePath);

# Copying starts here
$SourceStream = $SourceFile.OpenRead();
$DestinationStream = $DestinationFile.OpenWrite();

while ($SourceStream.Position -lt $SourceStream.Length) {
    try {

        $ReadLength = $SourceStream.Read($Buffer, 0, $Buffer.length);
        # If the read operation is successful, the current position of the stream is advanced by the number of bytes read. If an exception occurs, the current position of the stream is unchanged. (http://msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx)

    }
    catch [System.IO.IOException] {

        Write-Warning "System.IO.IOException at $($SourceStream.position) bit: $($_.Exception.message)"
        Write-Debug "Debugging...";

        $ShouldReadSize = [math]::Min([int64] $BufferSize, $SourceStream.Length - $SourceStream.Position);

        $DestinationStream.Write((New-Object System.Byte[] ($BufferSize)), 0, $ShouldReadSize);
        $SourceStream.Position = $SourceStream.Position + $ShouldReadSize;

        $UnreadableBits += $ShouldReadSize;

        continue;
    }
    catch {
        Write-Warning "Unhandled error at $($SourceStream.position) bit: $($_.Exception.message)";
        Write-Debug "Unhandled error. You should debug.";
        throw $_;
    }

    $DestinationStream.Write($Buffer, 0, $ReadLength);
    # Write-Progress -Activity "Hashing File" -Status $file -percentComplete ($total/$fd.length * 100)
}

$SourceStream.Dispose();
$DestinationStream.Dispose();

if ($UnreadableBits -ne 0) {Write-Host "$UnreadableBits bits are bad." -ForegroundColor "Red";}

Write-Host "Finished copying $SourceFilePath!" -ForegroundColor "Green";
1

Как вы заметили, /r:3 сделает три попытки вместо 1 миллиона (!)

/w:10 будет ждать 10 секунд между повторными попытками (по умолчанию 30).

Если вы делаете локальное копирование, я бы сделал две повторные попытки с 1-секундным ожиданием между ними (я оставляю 30-секундное ожидание при выполнении сетевых копий на случай, если я отключу кабель).

Также не используйте /mir как это приведет к удалению файлов в месте назначения, которых нет в источнике (что может иметь значение, если вы выполните эту команду несколько раз) - /E достаточно.

Если вы используете /copyall , не забудьте запустить командную строку от имени администратора, иначе он не сможет правильно настроить все ACL.

После этого chkdsk /r попытается восстановить файлы из поврежденных секторов.

0

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

0

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

источник назначения robocopy /e /XO /copy:DAT /r:3 /w:5

Или сократить периоды повторных попыток и ожидания.

По опыту / е является лучшим вариантом, чем / MIR, и тогда вам не понадобится / s

Кроме того, если ваша копия была прервана по какой-либо причине, используйте /XO, чтобы пропустить уже скопированные файлы.

Если вам нужен лог файлов в txt, используйте /log+:Files.log

Удобно, если это медиа.

На TechNet гораздо больше переключателей

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .