Python 使用ctypes创建的文件处理程序无效
我试图用python中的Python 使用ctypes创建的文件处理程序无效,python,ctypes,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)
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中,显式定义argtypes
、restype
和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")
您的代码在CloseHandle编辑后仍按原样工作 在
CreateFile()
中未关闭文件句柄时,在ReadAFile
中打开文件失败,因为该文件已打开。您没有检查错误,因此对ReadFile
的调用失败。现在,代码被编辑为在CreateFile
中具有CloseHandle
,它就可以工作了。注意,您可能需要关闭并重新打开IDE,因为它可能会保持文件的句柄打开,直到您终止该进程,因为它是一个句柄泄漏(我有这个问题)
我还发现,在ctypes中,显式定义argtypes
、restype
和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")
为什么你要使用ctypes来读/写文件?只是学习如何在python中使用ctypes作为课程的一部分。你应该在写完文件后调用
CloseHandle
。嘿@ekhumoro我在写完文件后尝试过了,结果是你可以读取一个没有使用ctypes创建的文件了吗?你为什么要使用ctypes来读呢读/写文件?只是学习如何在python中使用ctypes作为课程的一部分。在编写文件后,你应该调用CloseHandle
。嘿@ekhumoro,我在写入文件后尝试过了,结果是你可以读取一个没有使用ctypes创建的文件吗?谢谢标记!!当我将函数CreateFile和ReadFile作为两个独立的程序运行时,该程序可以工作。当我试图关闭CreateFile实例中的文件处理程序时,它会给我一个无效的处理程序错误,这似乎也会影响下一个函数。发生这种情况的原因是什么?@kvnbni正如我提到的,如果您在IDE中运行这些脚本并且出现故障,则可能会导致句柄泄漏。我提供的代码检查错误并已尝试/最终,因此如果读/写时出错,句柄仍将关闭。正确设置argtypes
和restype
也很重要。在64位系统上,默认返回值是32位int,句柄是64位的。有什么资源可以让我进一步了解这一点吗。谢谢你的帮助。真的很感激!!考虑使用<代码> CreateFileW <代码> >代码> LPCWSTR ,而不是<代码> CuraMeLea<代码>。在本例中,Python 2 ctypes会自动解码作为参数传递的字节字符串。它的默认转换是('mbcs','ignore')
,但我建议通过ctypes切换到严格的错误处理。设置转换模式('mbcs','strict')
(仅限2.x)。在Windows中,文件路径应该是Unicode的,但Python2对此需要一些规范。如果可以,请升级到3.6。此外,不要打开具有GENERIC\u ALL
访问权限的文件来读取它。使用GENERIC\u READ
。在这种情况下,您甚至可以使用FILE\u READ\u DATA
(1),其中CreateFile
将自动添加所需的最低访问权限:SYNCHRONIZE
和FILE\u READ\u ATTRIBUTES
。谢谢!!当我将函数CreateFile和ReadFile作为两个独立的程序运行时,该程序可以工作。当我试图关闭CreateFile实例中的文件处理程序时,它会给我一个无效的处理程序错误,这似乎也会影响下一个函数。发生这种情况的原因是什么?@kvnbni正如我提到的,如果您在IDE中运行这些脚本并且出现故障,则可能会导致句柄泄漏。我提供的代码检查错误并已尝试/最终,因此如果读/写时出错,句柄仍将关闭。正确设置argtypes
和restype
也很重要。在64位系统上,默认返回值是32位int,句柄是64位的。有什么资源可以让我进一步了解这一点吗。谢谢你的帮助。真的很感激!!考虑使用<代码> CreateFileW <代码> >代码> LPCWSTR ,而不是<代码> CuraMeLea<代码>。在本例中,Python 2 ctypes会自动解码作为参数传递的字节字符串。它的默认转换是('mbcs','ignore')
,但我建议通过ctypes切换到严格的错误处理。设置转换模式('mbcs','strict')
(仅限2.x)。在Windows中,文件路径应该是Unicode的,但Python2对此需要一些规范。如果可以,请升级到3.6。此外,不要打开具有GENERIC\u ALL
访问权限的文件来读取它。使用GENERIC\u READ
。在这种情况下,您甚至可以使用FILE\u READ\u DATA
(1),CreateFile
将自动向其中添加所需的最低访问权限:SYNCHRONIZE
和FILE\u READ\u ATTRIBUTES
。