对于以下Python代码:
fp = open('output.txt', 'wb')
# Very big file, writes a lot of lines, n is a very large number
for i in range(1, n):
fp.write('something' * n)
fp.close()
上述写作过程可持续30分钟以上。有时我会收到错误MemoryError
。关闭前文件的内容是存储在内存中还是写在临时文件中?如果它在临时文件中,它在Linux操作系统上的一般位置是什么?
修改
在for循环中添加了fp.write
答案 0 :(得分:5)
它存储在内存中的操作系统磁盘缓存中,直到由于时间或空间问题而隐式刷新到磁盘,或者显式地通过fp.flush()
。
答案 1 :(得分:3)
在Linux内核中会有写缓冲,但是在(ir)定期间隔它们将被刷新到磁盘。用完这样的缓冲区空间不应该导致应用程序级别的内存错误;缓冲区在此之前应该为空,在执行此操作时暂停应用程序。
答案 2 :(得分:2)
以ataylor对该问题的评论为基础:
您可能想要嵌套循环。像
这样的东西for i in range(1,n):
for each in range n:
fp.write('something')
fp.close()
这样,唯一被放入内存的是字符串"something"
,而不是"something" * n
。
答案 3 :(得分:1)
如果你写出一个写入可能会失败的大文件,你最好使用fp.flush()
定期将文件刷新到磁盘上。通过这种方式,文件将位于您选择的位置,您可以轻松获得而不是受操作系统的支配:
fp = open('output.txt', 'wb')
counter = 0
for line in many_lines:
file.write(line)
counter += 1
if counter > 999:
fp.flush()
fp.close()
这将每1000行将文件刷新到磁盘。
答案 4 :(得分:0)
如果你逐行写,那应该不是问题。您应该在写入之前显示您正在执行的操作的代码。首先,您可以尝试删除不必要的对象,使用fp.flush()
等。
答案 5 :(得分:0)
文件写入绝不应该出现内存错误;很可能,你在另一个地方有一些错误。
如果你有一个循环和一个内存错误,那么我会看看你是否“泄漏”了对象的引用。
类似的东西:
def do_something(a, b = []):
b.append(a)
return b
fp = open('output.txt', 'wb')
for i in range(1, n):
something = do_something(i)
fp.write(something)
fp.close()
我现在只是举个例子,但在实际情况下,参考泄漏可能更难找到;但是由于Python处理函数的默认参数的方式,这种情况只会泄漏do_something
内的内存。