硬盘驱动器损坏和 robocopy

硬盘驱动器损坏和 robocopy

在我的硬盘驱动器出现 CRC 错误我想将一个驱动器复制到另一个驱动器并购买了一个新的 1 TB 硬盘驱动器。

我正在使用以下命令:

robocopy G: J: /MIR /COPYALL /ZB

首先,它尝试复制文件几次(我没有数,它不再在我的窗口中),并收到拒绝访问错误,错误 5。然后它再次尝试并锁定。我尝试复制该特定文件(14 MB),Windows 显示“无法从源文件或磁盘读取”。

我再次启动了 robocopy。希望它在尝试失败一两次后会忽略它,但如果它不起作用,我可以使用什么选项来表示继续下一个文件?看起来它正在这样做,但对于最后一个文件,它重复了四次以上并最终锁定。

我愿意接受其他复制解决方案。我更喜欢内置解决方案。我使用的是 Windows 7。

另外,如果没有这个选项,我该怎么做呢/MIR/S /E够好吗?标记参考这里

我知道我可以使用/R:<Amount> 控制重试,但我仍然愿意接受其他解决方案。

它似乎需要几分钟才能决定尝试失败。我可以缩短它吗?文件现在已经停留在 20.8% 一段时间了。

我尝试了数据恢复应用程序。它尝试恢复数据,但并未将其标记为无效或损坏。虽然我确实收到了一条消息,说扇区 XYZ 出现 I/O 错误,是否继续?但这并没有给我损坏文件的名称。我不想要这个。对我来说最好的解决方案是获取所有好文件 + 无效文件的名称。

答案1

正如您所注意到的,/r:3将进行三次重试,而不是一百万次(!)

/w:10每次重试之间将等待 10 秒(默认为 30 秒)。

如果您正在进行本地复制,我会进行两次重试,每次重试之间间隔 1 秒(进行网络复制时我会等待 30 秒,以防电缆断掉)。

不要使用/mir,因为它将删除目标中源中不存在的文件(如果您多次运行此命令,这可能会产生影响) -/E就足够了。

如果您正在使用/copyall,请记住以管理员身份运行命令提示符,否则可能无法正确设置所有 ACL。

之后,chkdsk /r将尝试从坏扇区恢复文件。

答案2

我编写了一个 PowerShell 脚本来忽略复制时的设备 I/0 错误(从而用零替换不可读的数据)。 更新和更高级的版本可用这里。下面我放置的代码是第一个版本之一,并且尽可能简单:

## .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";

答案3

你最好使用以下数据恢复工具回取数据它知道驱动器发生故障并且会预期读取失败。

答案4

我使用 robocopy 进行设备间的所有备份传输。因为常规复制/粘贴不可靠,而且有些应用程序无法完全允许在复制失败时暂停或继续。

robocopy 源目标 /e /XO /copy:DAT /r:3 /w:5

或者缩短重试和等待时间。

从经验上看,/e 是比/和平号空间站那么你就不需要/s

此外,如果你的复制因某种原因被中断,请使用/XO跳过已经复制的文件。

如果你需要 txt 文件的日志,请使用/log+:文件.log

如果是媒体的话就很方便。

还有更多开关科技网

相关内容