2016-10-25 16 views
0

は、このプログラムを検討する:どの部門(win32file.FILE_FLAG_NO_BUFFERING)バッファ内のデータを揃える

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

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) 
関連する問題