我正在从外部驱动器(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());
}
}
谢谢你们!