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

时间:2018-01-02 20:05:06

标签: python ctypes

我试图在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")

1 个答案:

答案 0 :(得分:1)

您的代码在CloseHandle编辑后按原样运行。

如果您未在CreateFile()中关闭文件句柄,则ReadAFile中打开的文件将失败,因为该文件已经打开。您没有检查错误,因此您对ReadFile的调用失败了。现在编辑代码以使CloseHandle中的CreateFile成为可能。请注意,您可能需要关闭并重新打开IDE,因为它可能会保留对文件的句柄,直到您终止该过程,因为它是句柄泄漏(我遇到了这个问题)。

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

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")