IOException «Циклическая проверка избыточности» FileStream.CopyTo с использованием C # .Net - PullRequest
2 голосов
/ 18 августа 2011

У меня есть некоторый код C #, который использует FileStreams для открытия PhysicalDrive и получения образа всего диска, но последовательно выдает IOException с сообщением «Ошибка данных (проверка циклическим избыточным кодом)». После копирования около 121 МБ диска 128 МБ.

    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();
        }
    }
}

Я запустил Scan Disk на диске, о котором идет речь, и, похоже, с ним все в порядке. Если я изменю первый параметр CreateFile, чтобы просто прочитать раздел (а не то, что я хочу сделать), то изображение будет создано нормально.

Это продолжение реализации Windows C # команды linux dd , которую я пытался сделать.

UPDATE:

Дальнейшие исследования показывают, что ошибка связана с невозможностью получить или узнать свойство Src.Length. Я изменил свой код, чтобы копировать побайтово и вести подсчет, он выдает ошибки после 126959616 байт, что на 1 байт больше, чем общий размер изображения, созданного дд.

Ответы [ 2 ]

1 голос
/ 19 августа 2011

Причиной IOException было чтение после окончания потока.По какой-то причине, открывая физический диск как FileSteam, я не могу получить длину потока или иначе узнать его размер.Решение состоит в том, чтобы использовать объекты пространства имен System.Management для определения длины файла Device в байтах, а затем использовать Read, чтобы скопировать правильный объем данных из Stream.

Я думаю, причина того, что это произойдет после 121 МБ, кроется в том, что по ходу дела не используется 1024B на КБ, а вместо этого используется 1000B на КБ, так что это было немного красной селедкой с моей стороны.

Я до сих пор не понимаю, почему он выдает ошибку CRC, а не сообщение типа «Сектор не найден» или «Чтение за концом потока».

1 голос
/ 18 августа 2011

Циклическая проверка избыточности или ошибка «CRC» указывает на то, что диск поврежден или каким-то образом поврежден, возможно, является плохим местом на диске.Если вы видите это при попытке скопировать файл, это может быть связано с тем, что проблема может быть в самом файле.

Попробуйте скопировать файл на другой диск и посмотрите, работает ли он.

...