【问题标题】:Open a file in memory打开内存中的文件
【发布时间】:2014-05-26 12:32:50
【问题描述】:

(我正在开发一个 Python 3.4 项目。)

有一种方法可以在内存中打开(sqlite3)数据库:

    with sqlite3.connect(":memory:") as database:

open() 函数是否存在这样的技巧?类似的东西:

   with open(":file_in_memory:") as myfile:

这个想法是为了加速一些测试功能在磁盘上打开/读取/写入一些短文件;有没有办法确保这些操作发生在内存中?

【问题讨论】:

    标签: python file python-3.x


    【解决方案1】:

    StringIO怎么样:

    import StringIO
    
    output = StringIO.StringIO()
    output.write('First line.\n')
    print >>output, 'Second line.'
    
    # Retrieve file contents -- this will be
    # 'First line.\nSecond line.\n'
    contents = output.getvalue()
    
    # Close object and discard memory buffer --
    # .getvalue() will now raise an exception.
    output.close()
    

    python3:io.StringIO

    【讨论】:

      【解决方案2】:

      io.StringIO 提供了一个内存文件实现,您可以使用它来模拟真实文件。文档中的示例:

      import io
      
      output = io.StringIO()
      output.write('First line.\n')
      print('Second line.', file=output)
      
      # Retrieve file contents -- this will be
      # 'First line.\nSecond line.\n'
      contents = output.getvalue()
      
      # Close object and discard memory buffer --
      # .getvalue() will now raise an exception.
      output.close()
      

      在 Python 2 中,此类可用 StringIO.StringIO 代替。

      【讨论】:

        【解决方案3】:

        io.StringIO 中的字符串的类文件输入/输出有类似的东西。

        没有干净的方法可以将基于 url 的处理添加到正常的文件打开中,但是作为 Python 动态,您可以使用猴子补丁标准文件打开过程来处理这种情况。

        例如:

        from io import StringIO
        
        old_open = open
        in_memory_files = {}
        
        def open(name, mode="r", *args, **kwargs):
             if name[:1] == ":" and name[-1:] == ":":
                  # in-memory file
                  if "w" in mode:
                       in_memory_files[name] = ""
                  f = StringIO(in_memory_files[name])
                  oldclose = f.close
                  def newclose():
                      in_memory_files[name] = f.getvalue()
                      oldclose()
                  f.close = newclose
                  return f
             else:
                  return old_open(name, mode, *args, **kwargs)
        

        之后就可以写了

        f = open(":test:", "w")
        f.write("This is a test\n")
        f.close()
        
        f = open(":test:")
        print(f.read())
        

        请注意,此示例非常小,并不能处理所有真实文件模式(例如附加模式,或在读取模式下打开不存在的内存文件时引发适当的异常),但它可能适用于简单的案例。

        另请注意,所有内存中的文件都将永远保留在内存中(除非您还修补了unlink)。

        PS:我并不是说猴子补丁标准开放或StringIO 实例是一个好主意,只是你可以:-D

        PS2:这种问题在操作系统级别通过创建 in-ram 磁盘得到了更好的解决。有了它,您甚至可以调用外部程序从这些文件重定向它们的输出或输入,并且您还可以获得所有的全面支持,包括并发访问、目录列表等。

        【讨论】:

          猜你喜欢
          • 2011-09-07
          • 2010-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-24
          • 2017-04-27
          • 2014-02-14
          相关资源
          最近更新 更多