Python无法在r +模式下打开11gb csv但在r模式下打开

时间:2015-04-19 11:13:35

标签: python windows file-io

我遇到了一些循环通过一堆.csvs的代码的问题,如果没有任何内容(即以\n换行符结尾的文件),则删除最后一行

我的代码在除了一个文件之外的所有文件上成功运行,这是11gb目录中最大的文件。第二大文件是4.5gb。

它失败的线条只是:

with open(path_str,"r+") as my_file:

我收到以下消息:

IOError: [Errno 22] invalid mode ('r+') or filename: 'F:\\Shapefiles\\ab_premium\\processed_csvs\\a.csv'

我使用path_str创建os.file.join以避免错误,我尝试将文件重命名为a.csv,以确保文件名没有任何奇怪的内容。这没什么区别。

更奇怪的是,该文件很乐意在r模式下打开。即以下代码工作正常:

with open(path_str,"r") as my_file:

我尝试在读取模式下浏览文件,并且很乐意在文件的开头,结尾和中间读取字符。

有没有人知道Python可以处理的文件大小的限制或者为什么我可能会收到此错误?我使用的是Windows 7 64位,并且有16GB的RAM。

1 个答案:

答案 0 :(得分:19)

Python 2中的默认I / O堆栈在CRT FILE流上分层。在Windows上,它们建立在使用文件描述符的POSIX仿真API之上(文件描述符又分层在用户模式Windows API上,该API分层在内核模式I / O系统上,它本身就是一个深层次的系统基于I / O请求数据包;硬件在某处......)。在POSIX层中,使用_O_RDWR | _O_TEXT模式打开文件(如“r +”),需要搜索文件末尾以删除CTRL + Z(如果存在)。以下是CRT fopen文档的引用:

  

以文本(翻译)模式打开。在此模式下,CTRL + Z被解释为   输入中的文件结束字符。在为读/写而打开的文件中   使用“a +”,fopen检查文件末尾的CTRL + Z和   如果可能的话,删除它。这样做是因为使用fseek和ftell   在以CTRL + Z结尾的文件中移动,可能导致fseek表现   不正确地靠近文件的末尾。

这里的问题是上面的检查调用了32位_lseek(请记住,sizeof long在64位Windows上是4个字节,与大多数其他64位平台不同),而是_lseeki64。显然这对于​​11 GB的文件来说是失败的。具体来说,SetFilePointer失败,因为NULL的{​​{1}}值被调用。这是后一个调用的返回值和lpDistanceToMoveHigh

LastErrorValue

错误代码0x57为ERROR_INVALID_PARAMETER。当尝试从大文件的末尾进行搜索时,这是指0:000> kc 2 Call Site KERNELBASE!SetFilePointer MSVCR90!lseek_nolock 0:000> r rax rax=00000000ffffffff 0:000> dt _TEB @$teb LastErrorValue ntdll!_TEB +0x068 LastErrorValue : 0x57 lpDistanceToMoveHigh

要解决CRT NULL流的此问题,我建议您使用io.open打开文件。这是Python 3的I / O堆栈的向后移植实现。它始终以原始二进制模式(FILE)打开文件,并在原始层之上实现自己的缓冲和文本模式层。

_O_BINARY