"有更多数据和#34;从FileStream中读取时

时间:2014-10-22 12:11:39

标签: c# winapi windows-xp filestream handle

我正在从外部驱动器(LTO)读取数据,其中要读取的块大小是通过调用win32方法GetTapeParameters来定义的。它通常工作正常,但出于某种原因,我在阅读一个特定媒体时收到错误234“更多数据可用”。要读取的默认块大小为65536.如果我使用blocksize = blocksize * 16读取,则不再出现错误。

我特别要求读取预定大小,所以我真的不明白为什么读取的数据比预期长16倍。我错过了FileStream或Handle的东西吗?任何帮助表示赞赏。

我正在使用带有.Net 3.5的Windows XP,使用Win32 API与LTO驱动器进行通信。以下是一些代码:

创建FileStream:

FileStream = new FileStream(TapeHandle, FileAccess.Read, (int)BlockSize, true);

创建TapeHandle:

[DllImport("kernel32", SetLastError = true)]
internal static extern SafeFileHandle CreateFile(
        string lpFileName_,
        EFileAccessType dwDesiredAccess_,
        uint dwShareMode_,
        IntPtr lpSecurityAttributes_,
        EFileCreationDisposition dwCreationDisposition_,
        EFileAttributes dwFlagsAndAttributes_,
        IntPtr hTemplateFile_);

internal enum EFileAttributes : uint
    {
        FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
        FILE_FLAG_OVERLAPPED = 0x40000000,
        FILE_FLAG_NO_BUFFERING = 0x20000000,
        FILE_FLAG_RANDOM_ACCESS = 0x10000000,
        FILE_FLAG_WRITE_THROUGH = 0x80000000,
        FILE_ATTRIBUTE_READONLY = 0x1,
    }

private SafeFileHandle CreateTapeHandle(string tapeName_)
    {
        SafeFileHandle result = Win32.CreateFile(
            tapeName_, Win32.EFileAccessType.GENERIC_READ, 0, IntPtr.Zero, 
            Win32.EFileCreationDisposition.OPEN_EXISTING,
            Win32.EFileAttributes.FILE_FLAG_NO_BUFFERING | Win32.EFileAttributes.FILE_FLAG_OVERLAPPED |
            Win32.EFileAttributes.FILE_FLAG_BACKUP_SEMANTICS | Win32.EFileAttributes.FILE_FLAG_RANDOM_ACCESS |
            Win32.EFileAttributes.FILE_FLAG_WRITE_THROUGH,
            IntPtr.Zero);

        if (result.IsInvalid)
            DisplayWin32Error(Resources.ERROR_DEVICE);

        return result;
    }

的BeginRead:

internal byte[] Read()
    {
        DeviceStatus = Resources.DEVICE_READING;
        Debug.Assert(FileStream.CanRead);

        _stateObject.Buffer = new byte[BlockSize];
        _stateObject.Fs = FileStream;

        if (RestoreManager.Instance.RestoMode == RestoreManager.RestorationMode.Restoration)
            _stateObject.SetTimeOut();

        FileStream.BeginRead(
            _stateObject.Buffer, 0, _stateObject.Buffer.Length, EndReadAsyncCallback, _stateObject);

        WaitHandle.Reset();
        WaitHandle.WaitOne();
        FileStream.Flush();

        return _stateObject.Buffer;                                                                                      
    }

EndRead:

private void EndReadAsyncCallback(IAsyncResult ar_)
    {
        try
        {
            NbBytesRead = FileStream.EndRead(ar_);
            WaitHandle.Set();

            Debug.Assert(NbBytesRead <= BlockSize);
        }
        catch (Exception e)
        {
            Logger.LogError(Resources.ERROR_READ_FILE + " : " + e.Message);
            BackupReader.Instance.OnReadFailed(new EventArgs());
        }
    }

谢谢你们!

0 个答案:

没有答案