我使用了hashlib(它取代了Python 2.6/3.0中的md5),如果我打开一个文件并将其内容放入hashlib.md5()
函数中,它工作正常.
问题在于非常大的文件,它们的大小可能超过RAM大小.
如何在不将整个文件加载到内存的情况下获取文件的MD5哈希值?
我设置了gunicorn与3名工人30个工人连接并使用eventlet工人类.它是在Nginx背后设置的.在每几个请求之后,我在日志中看到了这一点.
[ERROR] gunicorn.error: WORKER TIMEOUT (pid:23475)
None
[INFO] gunicorn.error: Booting worker with pid: 23514
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我怎么能弄清楚什么是错的?
谢谢
[编辑:此问题仅适用于32位系统.如果你的计算机,你的操作系统和你的python实现是64位的,那么mmap-ing巨大的文件可以正常工作并且非常高效.
我正在编写一个模块,其中包括允许按位读取文件访问.这些文件可能很大(数百GB),所以我编写了一个简单的类,让我像处理字符串一样处理文件并隐藏所有的搜索和阅读.
当我写我的包装类时,我不知道mmap模块.在阅读mmap的文档时,我认为"很棒 - 这正是我所需要的,我将取出我的代码并用mmap替换它.它可能效率更高,删除代码总是好的."
问题是mmap不适用于大文件!这对我来说非常令人惊讶,因为我认为它可能是最明显的应用程序.如果文件超过几千兆字节,那么我得到一个EnvironmentError: [Errno 12] Cannot allocate memory
.这只发生在32位Python构建中,所以它似乎耗尽了地址空间,但我找不到任何关于此的文档.
我的代码就是
f = open('somelargefile', 'rb')
map = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是我错过了一些明显的东西吗?有没有办法让mmap可以在大文件上移植,或者我应该回到我天真的文件包装器?
更新:似乎有一种感觉,Python mmap应该具有与POSIX mmap相同的限制.为了更好地表达我的挫败感,这是一个简单的类,它具有mmap的一小部分功能.
import os
class Mmap(object):
def __init__(self, f):
"""Initialise with a file object."""
self.source = f
def __getitem__(self, key):
try:
# A slice
self.source.seek(key.start, os.SEEK_SET)
return self.source.read(key.stop - key.start)
except AttributeError:
# single element
self.source.seek(key, os.SEEK_SET)
return self.source.read(1)
Run Code Online (Sandbox Code Playgroud)
它是只读的,并没有做任何花哨的事情,但我可以像使用mmap一样:
map2 = Mmap(f)
print map2[0:10]
print map2[10000000000:10000000010]
Run Code Online (Sandbox Code Playgroud)
除了文件大小没有限制.真的不太难......
我正在编写一个代码,一次取一个巨大的文本文件(几GB)N行,处理该批处理,并移动到下一行N行,直到我完成整个文件.(我不在乎最后一批是不是完美的尺寸).
我一直在阅读有关使用itertools islice进行此操作的信息.我想我在那里:
from itertools import islice
N = 16
infile = open("my_very_large_text_file", "r")
lines_gen = islice(infile, N)
for lines in lines_gen:
...process my lines...
Run Code Online (Sandbox Code Playgroud)
麻烦的是我想处理下一批16行,但我遗漏了一些东西
我需要一次读取最多N行读取一个大文件,直到EOF.在Python中最有效的方法是什么?就像是:
with open(filename, 'r') as infile:
while not EOF:
lines = [get next N lines]
process(lines)
Run Code Online (Sandbox Code Playgroud) 我知道怎么yield
运作.我知道排列,认为它只是一个简单的数学.
但是什么yield
是真正的力量?我应该什么时候使用它?一个简单而好的例子就更好了.
在Python中,对于二进制文件,我可以这样写:
buf_size=1024*64 # this is an important size...
with open(file, "rb") as f:
while True:
data=f.read(buf_size)
if not data: break
# deal with the data....
Run Code Online (Sandbox Code Playgroud)
有了我想逐行阅读的文本文件,我可以这样写:
with open(file, "r") as file:
for line in file:
# deal with each line....
Run Code Online (Sandbox Code Playgroud)
这是简写:
with open(file, "r") as file:
for line in iter(file.readline, ""):
# deal with each line....
Run Code Online (Sandbox Code Playgroud)
这个成语记录在PEP 234中,但我找不到二进制文件的类似习惯用法.
我试过这个:
>>> with open('dups.txt','rb') as f:
... for chunk in iter(f.read,''):
... i+=1
>>> i
1 # 30 MB file, …
Run Code Online (Sandbox Code Playgroud) 我正在读取python 2.7中的800 GB xml文件,并使用etree迭代解析器解析它.
目前,我只使用open('foo.txt')
没有缓冲参数.我有点困惑这是我应该采取的方法,还是我应该使用缓冲参数或使用io中的东西,如io.BufferedReader或io.open或io.TextIOBase.
正确方向的一点将非常感激.
有两个文件,分别是FileA和FileB,我们需要找到FileA中所有的编号,而FileB中没有这些编号。FileA中的所有数字均已排序,FileB中的所有数字均已排序。例如,
输入:
FileA = [1, 2, 3, 4, 5, ...]
FileB = [1, 3, 4, 6, ...]
Run Code Online (Sandbox Code Playgroud)
输出:
[2, 5, ...]
Run Code Online (Sandbox Code Playgroud)
内存非常有限,甚至无法一次将一个完整的文件加载到内存中。同样需要线性或更短的时间复杂度。
因此,如果文件足够小以适合内存,我们可以加载它们并将其内容初始化为两个集合,然后取一个集合差,以便以O(1)或恒定时间复杂度解决问题。
set(contentsofFileA)-set(contentsofFileB)
Run Code Online (Sandbox Code Playgroud)
但是由于文件太大,它们将无法完全加载到内存中,因此这是不可能的。
同样,另一种方法是在批处理中使用蛮力方法。因此,我们从FileA加载数据块或一批,然后从FileB加载数据块,然后比较它,然后再从FileB加载下一个数据块,依此类推。然后,在对FileB中的所有元素进行FileA块检查之后,再从FileA加载下一批,然后继续进行。但这会产生O(n ^ 2)或二次时间复杂度,对于具有大条目的超大文件而言效率不高。
需要以线性或更短的时间复杂度来解决该问题,并且不将整个文件加载到内存中。有什么帮助吗?
我正在解析一个20Gb的文件,并将符合某种条件的行输出到另一个文件,但偶尔python会同时读取2行并连接它们.
inputFileHandle = open(inputFileName, 'r')
row = 0
for line in inputFileHandle:
row = row + 1
if line_meets_condition:
outputFileHandle.write(line)
else:
lstIgnoredRows.append(row)
Run Code Online (Sandbox Code Playgroud)
我检查了源文件中的行结尾,并将它们检出为换行符(ascii char 10).拉出问题行并在隔离中解析它们按预期工作.我在这里遇到一些python限制吗?第一个异常文件中的位置大约是4GB标记.