考虑这个程序:
import win32file
src_file = win32file.CreateFile(
r'C:\test.rar',
win32file.GENERIC_READ,
win32file.FILE_SHARE_READ,
None,
win32file.OPEN_EXISTING,
win32file.FILE_FLAG_NO_BUFFERING,
None
)
dst_file = win32file.CreateFile(
r'D:\test.rar',
win32file.GENERIC_WRITE,
win32file.FILE_SHARE_WRITE,
None,
win32file.CREATE_ALWAYS,
win32file.FILE_FLAG_NO_BUFFERING,
None
)
while True:
rc, data = win32file.ReadFile(src_file, 4096)
if not data:
break
else:
win32file.WriteFile(dst_file, data)
src_file.close()
dst_file.close()
写入最新数据文件失败时: pywintypes.error:(87,' WriteFile','参数不正确。')
这是FILE_FLAG_NO_BUFFERING标志所期望的行为,但我不知道如何在python中解决它。
答案 0 :(得分:0)
您可以使用ctypes。请注意,FILE_FLAG_NO_BUFFERING需要以扇区大小的倍数进行写入,因此除非您希望目标文件大于源文件,否则您可能希望使用不同的设置进行写入。我使用了FILE_FLAG_WRITE_THROUGH:
import ctypes
import ctypes.wintypes
import sys
src_filename = sys.argv[0]
dst_filename = sys.argv[0] + ".test.backup"
CloseHandle = ctypes.windll.kernel32.CloseHandle
CreateFile = ctypes.windll.kernel32.CreateFileA
ReadFile = ctypes.windll.kernel32.ReadFile
WriteFile = ctypes.windll.kernel32.WriteFile
FILE_SHARE_READ = 1
FILE_SHARE_WRITE = 2
FILE_FLAG_NO_BUFFERING = 0x20000000
CREATE_ALWAYS = 2
OPEN_EXISTING = 3
OPEN_ALWAYS = 4
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
INVALID_HANDLE_VALUE = ctypes.wintypes.HANDLE(-1).value
INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF
FILE_FLAG_WRITE_THROUGH = 0x80000000
hSrc = CreateFile(
src_filename,
GENERIC_READ,
FILE_SHARE_READ,
None,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING,
None
)
hDest = CreateFile(
dst_filename,
GENERIC_WRITE,
FILE_SHARE_WRITE,
None,
OPEN_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
None
)
def ctypes_alloc_aligned(size, alignment):
"""
http://stackoverflow.com/questions/8658813/control-memory-alignment-in-python-ctypes
"""
bufSize = size+(alignment-1)
raw_memory = bytearray(bufSize)
ctypes_raw_type = (ctypes.c_char * bufSize)
ctypes_raw_memory = ctypes_raw_type.from_buffer(raw_memory)
raw_address = ctypes.addressof(ctypes_raw_memory)
offset = raw_address % alignment
offset_to_aligned = (alignment - offset) % alignment
ctypes_aligned_type = (ctypes.c_char * (bufSize-offset_to_aligned))
ctypes_aligned_memory = ctypes_aligned_type.from_buffer(raw_memory, offset_to_aligned)
return ctypes_aligned_memory
sectorSize = 4096
bufSize = 256*sectorSize # 1MB
lpBuffer = ctypes_alloc_aligned(bufSize, sectorSize)
numBytes = ctypes.wintypes.DWORD()
while True:
bSuccess = ctypes.windll.kernel32.ReadFile(
hSrc, lpBuffer, bufSize, ctypes.byref(numBytes), None)
if not bSuccess:
print "ReadFile FAILED:", hSrc, numBytes
raise ctypes.WinError()
if numBytes.value == 0:
break
bSuccess = ctypes.windll.kernel32.WriteFile(
hDest, lpBuffer, numBytes, ctypes.byref(numBytes), None)
if not bSuccess:
print "WriteFile FAILED:", hDest, numBytes
raise ctypes.WinError()
CloseHandle(hSrc)
CloseHandle(hDest)