我遇到了一些循环通过一堆.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。
答案 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