Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

After my HD gave me crc errors I wanted to copy one drive to another and picked up a new 1TB hd.

I am using the command robocopy G: J: /MIR /COPYALL /ZB

First it tried copying the file a few times (i didnt count, its not in my window anymore) and got an access denied error, error 5. Then it tried again and locked up. I tried copying that specific file (14mb) and windows says "cant read from source file or disk".

I started robocopy again. Hopefully it will ignore it after a fail attempt or two but what options can i use to say if it doesnt work continue to the next file. It looked like that is what it was doing but for this last one it repeated more then 4times and locked up finally.

I'm open to other copy solutions. I do prefer built in solutions. I am using windows 7

Also how might i do this without the /MIR option. Is /S /E good enough? flag reference here

-edit- i see i can control retries with /R: but i am still open to alternative solutions.

-edit2- It seems to take a few minutes before it decides the try failed. Can i shorten it? The file has been stuck at 20.8% for quiet a while now.

-edit3- I tried a data recovery app. It tried to recover the data and DID NOT mark it as invalid or corrupted. Although i did get a msg saying sectory XYZ had an IO error, continue? but that didnt give me the name of the corrupted file. I dont want this. Best solution for me is getting all good files + names of invalid files.

share|improve this question

3 Answers 3

up vote 2 down vote accepted

as you've noticed, /r:3 will do 3 retries instead of 1 million(!)

/w:10 will wait 10 seconds between retries (default is 30)

if you're doing a local copy, I'd do 2 retries with a 1 second wait between them (I keep the 30 second wait when doing network copies in case I knock the cable out)

also do not use /mir as it will delete files in the destination that don't exist in the source (which might matter if you run this command several times) - /E is sufficient

if you're using /copyall, remember to run the command prompt as adminstrator or it probably won't be able to set all the ACLs properly

afterwards, chkdsk /r will try to recover files from bad sectors

share|improve this answer

I wrote a little powershell script to ignore the device I/0 errors on copy (and thus replace unreadable data with zero's). An updated and more advanced version is available here. The code that I have placed here below is one of the first versions and as simple as possible:

## .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 fo accuracy, use small buffer, smallest being the cluter size of the partition where your sourcefile 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 cluser 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";
share|improve this answer

You will be better off using data recovery tools like GetDataBack which are aware of the failed drive and will expect failed reads.

share|improve this answer
    
Would it try recover the bad data and give me an invalid partially recovered file? I may rather not have that or at least marked as partial/invalid file. –  acidzombie24 May 16 '10 at 4:32
    
It looks like it will try to recover the file and will not mark it as invalid/corrupted. I dont want this. But good idea with data recovery app. –  acidzombie24 May 16 '10 at 5:27
    
When you use the file system browser it will indicate if the file contains bad sectors. –  ta.speot.is May 17 '10 at 4:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.