使用 ctypes 创建的文件处理程序无效

File Handler created using ctypes is invalid

我试图在 python 中使用 ctypes 创建一个新文件。该文件已创建,我可以写入其中。当我尝试读取此文件时,问题就开始了。它给了我一个无效的文件句柄错误。任何人都可能知道为什么会这样。

以下是我使用的代码:

from ctypes import *

def CreateFile(file_name='',data=''):

    file_handler=windll.Kernel32.CreateFileA(file_name,0x10000000,0,None,4,0x80,None)

    pointer_to_written_data=c_int(0)
    windll.Kernel32.WriteFile(file_handler,data,len(data),byref(pointer_to_written_data),None)
    windll.Kernel32.CloseHandle(file_handler)
    return

def ReadAFile(file_name=''):

    file_handler=windll.Kernel32.CreateFileA(file_name,0x10000000,0,None,4,0x80,None)
    data=create_string_buffer(4096)
    pointer_to_read_data=c_int(0)
    if(windll.Kernel32.ReadFile(file_handler,byref(data),1024,byref(pointer_to_read_data),None)==0):
            print "Failed"
    print windll.Kernel32.GetLastError()
    windll.Kernel32.CloseHandle(file_handler)
    print data.value
    return

CreateFile("sample.txt","This is a test file!!")
ReadAFile("sample.txt")

您的代码在 CloseHandle 编辑后可以正常工作。

当您未在 CreateFile() 中关闭文件句柄时,在 ReadAFile 中打开文件失败,因为该文件已经打开。您没有检查错误,因此您对 ReadFile 的调用失败。既然代码被编辑为在 CreateFile 中包含 CloseHandle,它就可以工作了。请注意,您可能需要关闭并重新打开 IDE,因为它可能会保持对文件的句柄打开,直到您终止该进程,因为它是句柄泄漏(我有那个问题)。

我还发现在 ctypes 中明确定义 argtypesrestypeerrcheck 很有用。 errcheck 特别是,因为代码会抛出错误,您不必检查 return 值是否失败。

from ctypes import *
from ctypes import wintypes as w

INVALID_HANDLE_VALUE = w.HANDLE(-1).value
GENERIC_ALL = 0x10000000
OPEN_ALWAYS = 4
FILE_ATTRIBUTE_NORMAL = 0x80

_k32 = WinDLL('kernel32',use_last_error=True)
_CreateFileA = _k32.CreateFileA
_WriteFile = _k32.WriteFile
_ReadFile = _k32.ReadFile
_CloseHandle = _k32.CloseHandle

def validate_handle(result,func,args):
    if result == INVALID_HANDLE_VALUE:
        raise WindowsError(get_last_error())
    return result

def validate_bool(result,func,args):
    if not result:
        raise WindowsError(get_last_error())

_CreateFileA.argtypes = w.LPCSTR,w.DWORD,w.DWORD,c_void_p,w.DWORD,w.DWORD,w.HANDLE
_CreateFileA.restype = w.HANDLE
_CreateFileA.errcheck = validate_handle
_WriteFile.argtypes = w.HANDLE,c_void_p,w.DWORD,POINTER(w.DWORD),c_void_p
_WriteFile.restype = w.BOOL
_WriteFile.errcheck = validate_bool
_ReadFile.argtypes = w.HANDLE,w.LPVOID,w.DWORD,POINTER(w.DWORD),c_void_p
_ReadFile.restype = w.BOOL
_ReadFile.errcheck = validate_bool
_CloseHandle.argtypes = w.HANDLE,
_CloseHandle.restype = w.BOOL
_CloseHandle.errcheck = validate_bool

def CreateFile(file_name='',data=''):
    file_handler = _CreateFileA(file_name,GENERIC_ALL,0,None,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,None)
    written = w.DWORD()
    try:
        _WriteFile(file_handler,data,len(data),byref(written),None)
    finally:
        _CloseHandle(file_handler)

def ReadAFile(file_name=''):
    file_handler = _CreateFileA(file_name,GENERIC_ALL,0,None,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,None)
    data = create_string_buffer(4096)
    read = w.DWORD()
    try:
        _ReadFile(file_handler,byref(data),1024,byref(read),None)
    finally:
        _CloseHandle(file_handler)
    print data.value

CreateFile("sample.txt","This is a test file!!")
ReadAFile("sample.txt")