【发布时间】:2020-07-26 12:29:04
【问题描述】:
我编写了可以从物理磁盘写入和读取数据的代码。 我使用 pInvoke CreateFile 打开物理磁盘,并使用 FileStream 执行读取和写入数据。
当物理磁盘在线时,一切正常。
如果物理磁盘脱机并且我尝试写入磁盘,则会收到错误消息 System.IO.IOException: '媒体被写保护。'
如何在不尝试写入磁盘的情况下检测磁盘是否脱机。
这是创建 FileStream 并执行写入磁盘的代码
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const uint OPEN_EXISTING = 3;
private const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
private const uint FILE_FLAG_WRITE_THROUGH = 0x80000000;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
public void OpenFile()
{
m_handleValue = CreateFile(DevicePath, GENERIC_WRITE | GENERIC_READ,
0x3, IntPtr.Zero, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH
, IntPtr.Zero);
m_fileStream = new FileStream(m_handleValue, FileAccess.ReadWrite, 512);
}
public void WriteData(int offset, byte[] data)
{
m_fileStream.Seek(offset, SeekOrigin.Begin);
m_fileStream.Write(data, 0, data.Length);
}
【问题讨论】:
-
事实上,不可能 100% 确定地知道,因为您依赖该设备的设备驱动程序来正确准确地将其状态报告给 Windows。 Windows 向您提供错误消息“媒体已写保护”。 因为它认为设备在线且已连接但受写保护,如果 Windows 认为设备离线或不可用,它会给您不同的错误消息和错误代码。
-
你为什么要重新实现
CreateFile?您的声明不会添加任何FileStream的构造函数中不存在的任何功能。 -
无论如何,您都希望使用 WMI 来检查设备状态,而不是 Win32 的
CreateFile。也就是说,可能实际上允许抛出异常 - 但前提是离线/不可用设备确实是一个异常情况。 -
我没有重新实现 CreateFile,我将它与标志一起使用,因此我可以跳过操作系统(使用 FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH)
-
这些选项也可以通过其他 FileStream 构造函数重载获得。
标签: c# pinvoke filehandle