【问题标题】:Does the Python "open" function save its content in memory or in a temp file?Python“打开”函数是否将其内容保存在内存或临时文件中?
【发布时间】:2011-01-15 10:37:17
【问题描述】:

对于以下 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

【问题讨论】:

  • 您实际上是在多次调用fp.write,还是将它们全部收集在一个大字符串中并一次写出?后者效率相当低。
  • 它在for循环中调用多次写入。
  • 显示代码。如果你一行一行地写,应该没有问题。
  • 'something' * n 将在每次迭代中构建,并且随着 n 的增加将变得相当大。您的 MemoryError 可能与此有关。

标签: python


【解决方案1】:

它存储在内存中操作系统的磁盘缓存中,直到它被刷新到磁盘,无论是由于时间或空间问题而隐含地,还是通过fp.flush() 显式地刷新。

【讨论】:

  • 修改问题后,现在很明显'something' * nn 变大时会导致严重的内存问题。文件写入与'something' * n耗尽内存无关。
【解决方案2】:

Linux 内核中会有写缓冲,但会定期(或)定期将它们刷新到磁盘。用完这样的缓冲区空间永远不会导致应用程序级内存错误;缓冲区应该在此之前清空,同时暂停应用程序。

【讨论】:

    【解决方案3】:

    如果您要写出一个写入可能会失败的大文件,您最好使用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】:

      如果你逐行写,应该没有问题。您应该在编写之前显示您正在做什么的代码。首先,您可以尝试删除不需要的对象,使用fp.flush() 等。

      【讨论】:

        【解决方案5】:

        文件写入不应该出现内存错误;很可能,您在另一个地方有一些错误。

        如果您有一个循环和内存错误,那么我会查看您是否“泄漏”了对对象的引用。
        比如:

        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 内部的内存。

        【讨论】:

          【解决方案6】:

          基于ataylor对该问题的评论:

          您可能想要嵌套循环。像

          for i in range(1,n):
              for each in range n:
                  fp.write('something')
          fp.close()
          

          那样,唯一被放入内存的是字符串"something",而不是"something" * n

          【讨论】:

          • +1:为较大的n 值创建"something" * n 将耗尽内存。写入文件占用的内存非常少。
          猜你喜欢
          • 1970-01-01
          • 2021-03-18
          • 2015-10-19
          • 2020-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多