axe*_*axe 4 .net c# winapi createfile
我需要以原始模式打开读取磁盘,因此我使用 CreateFile API 函数来实现此目的。
private static FileStream OpenDisk(string drive)
{
// Try to open hard disk drive in raw mode for reading
SafeFileHandle safeHandle = Native.CreateFile(
string.Format(@"\\.\{0}", drive),
FileAccess.Read,
FileShare.Read,
IntPtr.Zero,
FileMode.Open,
FileAttributes.ReadOnly | FileAttributes.Device,
IntPtr.Zero);
// Check if the drive was successfully opened
if (safeHandle.IsInvalid)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
// Create file stream on the file for reading
return new FileStream(safeHandle, FileAccess.Read);
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试从流中读取时出现以下错误
Handle does not support synchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened asynchronously (that is, it was opened explicitly for overlapped I/O).
这是重现此问题的示例代码
using (FileStream stream = OpenDisk("X:"))
{
byte[] buffer = new byte[1000];
while (stream.Read(buffer, 0, 1000) > 0) { }
}
Run Code Online (Sandbox Code Playgroud)
我真的不明白它想从我这里得到什么?当我使用更大的缓冲区(例如 4096)时它可以工作。当我说它有效时,我的意思是它确实有效(总是),它工作了一段时间,直到我更改缓冲区大小。我猜它在内部做了某种异步缓冲,当我指定比默认缓冲大小更大的缓冲区时,它只是不被使用,但如何摆脱这个?
谢谢
更新
当我尝试使用 BufferedStream 读取它时,我遇到了同样的问题
using (BufferedStream stream = new BufferedStream(OpenDisk("X:"), 4096))
{
byte[] buffer = new byte[1000];
while (stream.Read(buffer, 0, 1000) > 0) { }
}
Run Code Online (Sandbox Code Playgroud)
我是否理解了 BufferedStream 的错误目的?它不应该读取并缓存指定大小的块吗?
简而言之,卷中的读取是非缓冲的,并且必须是整个扇区的。4096 的缓冲区大小可以实现此目的。该错误消息具有误导性,因为异步 I/O 和非缓冲往往会同时出现。一些细节:
即使在 CreateFile 中未指定非缓存选项,卷句柄也可以由特定文件系统自行决定以非缓存方式打开。您应该假设所有 Microsoft 文件系统都以非缓存方式打开卷句柄。文件非缓存 I/O 的限制也适用于卷。
来自文件缓冲文档:
归档时间: |
|
查看次数: |
4322 次 |
最近记录: |