这是this question的后续行动。我想知道你是否可以在写作模式下访问原始设备(例如\\.\PhysicalDriveN
),如果是这种情况,那该怎么做。
使用Linux,只需使用例如,即可实现写访问。 open("/dev/sdd", "w+")
(前提是脚本以root权限运行)。我假设Mac OS的行为相似(输入文件为/dev/diskN
)。
在Windows下尝试相同的命令(使用相应的路径)时,它会失败,并显示以下错误:
IOError: [Errno 22] invalid mode ('w+') or filename: '\\\\.\\PhysicalDrive3'
但是,当尝试从PhysicalDrive 读取时,可以正常工作(即使读取正确的数据)。 shell在Windows 7下以管理员权限运行。
有没有其他方法可以使用python完成此任务,同时仍然保持脚本尽可能与平台无关?
我进一步研究了python为文件处理提供了哪些方法,并偶然发现了os.open。使用os.open(drive_string, os.O_WRONLY|os.O_BINARY)
打开PhysicalDrive不会返回任何错误。到现在为止还挺好。现在我可以选择使用os.write直接写入此文件描述符,或使用os.fdopen获取文件对象并以常规方式写入。
可悲的是,这些可能性都不起作用。在第一种情况下(os.write()
),我得到了这个:
>>> os.write(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "test")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
在第二种情况下,我可以创建一个具有写权限的文件对象,但写入本身失败(好吧,在使用.flush()
强制执行后):
>>> g = os.fdopen(os.open("\\\\.\\PhysicalDrive3", os.O_WRONLY|os.O_BINARY), "wb")
>>> g.write("test")
>>> g.flush()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
答案 0 :(得分:14)
正如eryksun和agf在评论中指出的那样(但我一开始并没有真正得到它),解决方案很简单:你必须在{{1}中打开设备模式,它打开updating的设备(正如我现在发现的那样......),而不是尝试用新文件替换它(因为文件实际上是一个物理驱动器,所以无法工作)。
写入时,必须一次写入整个扇区(即512字节的倍数),否则会失败。
此外,rb+
命令也可以仅按扇区跳转。如果您尝试在扇区内寻找一个位置(例如位置.seek()
),文件对象将跳转到您请求的位置所在的扇区的开头(即到第二个扇区的开头,字节{{1 }})。
答案 1 :(得分:0)
可能在Win 7中你必须做一些更极端的事情,比如事先用DeviceIoControl(hVol,FSCTL_LOCK_VOLUME,......)锁定磁盘的音量
在Win 7中你不必这样做;使用'rb +'模式打开和书写工作正常。