IOException“;循环格式副本检查“;FileStream.CopyTo使用C#.Net
我有一些C#代码,它使用FileStreams打开一个物理驱动器并拍摄整个磁盘的映像,但在复制了一个128MB磁盘的大约121MB后,它始终抛出一个IOException,并显示消息“数据错误(循环冗余检查)”IOException“;循环格式副本检查“;FileStream.CopyTo使用C#.Net,c#,filestream,C#,Filestream,我有一些C#代码,它使用FileStreams打开一个物理驱动器并拍摄整个磁盘的映像,但在复制了一个128MB磁盘的大约121MB后,它始终抛出一个IOException,并显示消息“数据错误(循环冗余检查)” using Microsoft.Win32.SafeHandles; using System.IO; using System; [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingCon
using Microsoft.Win32.SafeHandles;
using System.IO;
using System;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
protected static extern SafeFileHandle CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr SecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
public void MakeImage()
{
SafeFileHandle TheDevice = null;
try
{
TheDevice = CreateFile(@"\\.\PHYSICALDRIVE1", (uint)FileAccess.Read, (uint)0, IntPtr.Zero, (uint)FileMode.Open, (uint)FILE_ATTRIBUTE_SYSTEM, IntPtr.Zero);
if (TheDevice.IsInvalid) { throw new IOException("Unable to access drive. Win32 Error Code " + Marshal.GetLastWin32Error()); }
using (FileStream Dest = System.IO.File.Open("output.bin", FileMode.Create))
{
using (FileStream Src = new FileStream(TheDevice, FileAccess.Read))
{
Src.CopyTo(Dest);
Src.Close();
}
Dest.Close();
}
}
catch(Exception Ex)
{
//Here is where i am getting the IOException
//Handle error..
}
finally
{
if (TheDevice != null)
{
if (!TheDevice.IsClosed)
TheDevice.Close();
TheDevice.Dispose();
}
}
}
我在有问题的驱动器上运行了扫描磁盘,它似乎没有任何问题。如果我将CreateFile的第一个参数更改为只读取一个分区(不是我想做的),那么图像就可以很好地创建
这是我一直试图做的后续工作
更新:
进一步的调查表明,该错误与无法获取或不知道Src.Length属性有关。我将代码更改为逐字节复制并保留计数,它在126959616字节后出错,这比dd生成的映像的总大小多1字节。循环冗余检查或“CRC”错误表示磁盘以某种方式损坏或损坏,可能是磁盘上的一个坏点。如果您在尝试复制文件时看到它,则可能是文件本身存在缺陷
尝试将文件复制到其他磁盘,看看是否有效。IOException的原因是读取超过流的结尾。由于某些原因,当以文件组的形式打开物理磁盘时,我无法获得流的长度或以其他方式确定其大小。解决方案是使用System.Management命名空间对象找出设备文件的长度(以字节为单位),然后使用Read从流中复制正确数量的数据 我认为在121MB之后会发生这种情况的原因是,在这个过程中,没有使用1024B到KB,而是使用1000B到KB,所以这对我来说是一个小麻烦
我仍然不明白为什么它会抛出CRC错误,而不是“未找到扇区”或“读取超过流末尾”类型的消息。重新格式化驱动器。如果失败,请扔掉它(应该)。CreateFile(“\\。\PHYSICALDRIVE1”,…这不应该起作用,C#应该将\P解释为转义序列,除非在字符串前面添加@…@Hinek抱歉,我的错误,我将编辑代码列表以澄清这一点。@Hans Passant尝试格式化磁盘,但仍然失败,因此我将磁盘换成另一个(256MB大小)在245MB之后,它失败了,出现了同样的错误。我不得不猜测这些是带有FAT32文件系统的闪存驱动器。通过在FAT中保留一个特殊条目来标记坏集群。在闪存驱动器上有坏集群并不罕见。您的代码将看到它们。并轰炸它们。您的任务得到了更多的补偿复杂。另一种情况是,我正在将磁盘复制到一个文件。我尝试复制磁盘并在另一个磁盘上定位目标/输出文件,但在128MB磁盘的121MB之后,它仍然抛出IOException。这可能意味着您正在复制的原始磁盘在121MB之后以某种方式损坏。大小的差异是du对于某些应用程序,将Kb/Mb计算为1000字节/Kb,而不是1024字节,因此它复制了整个128MB,但当它超过末尾时失败。