python - 使用 win32file.ReadFile 读取文件

beg*_*er_ 5 python pywin32 readfile

类似问题:

使用 win32file.ReadFile 从管道获取输出的正确方法是什么?

然而,我的问题在那个问题中没有得到回答。当我打电话

result, data = win32file.ReadFile(my_file, 4096, None)
Run Code Online (Sandbox Code Playgroud)

结果始终为 0,根据文档,这意味着成功:

The result is a tuple of (hr, string/PyOVERLAPPEDReadBuffer), where hr may be 0, 
ERROR_MORE_DATA or ERROR_IO_PENDING.
Run Code Online (Sandbox Code Playgroud)

即使我将缓冲区设置为 10 并且文件大得多,结果也是 0 并且数据是包含前 10 个字符的字符串。

result, buf = win32file.ReadFile(self._handle, 10, None)  
while result == winerror.ERROR_MORE_DATA:            
    result, data = win32file.ReadFile(self._handle, 2048, None)
    buf += data   
    print "Hi"
return result, buf
Run Code Online (Sandbox Code Playgroud)

即使文件明显包含更多数据,也永远不会打印“嗨”。我的问题是如何确保在不使用荒谬的大缓冲区的情况下读取整个文件?

beg*_*er_ 2

正如已经观察到的那样,如果win32file.ReadFile结果值为hr0,则表示成功。这与 win32 api 文档正好相反,win32 api 文档说 0 表示发生错误。

要确定读取了多少字节,您需要检查返回字符串的长度。如果它与缓冲区大小相同,则可能有更多数据。如果它更小,则整个文件已被读取:

def readLines(self):
    bufSize = 4096
    win32file.SetFilePointer(self._handle, 0, win32file.FILE_BEGIN)
    result, data = win32file.ReadFile(self._handle, bufSize, None) 
    buf = data
    while len(data) == bufSize:            
        result, data = win32file.ReadFile(self._handle, bufSize, None)
        buf += data
    return buf.split('\r\n')
Run Code Online (Sandbox Code Playgroud)

您需要为此添加错误处理,例如。检查结果是否为0,如果不为0则采取相应措施。