在内存中打开一个文件

时间:2014-04-12 08:29:27

标签: python file python-3.x

(我正在研究Python 3.4项目。)

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

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

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

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

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

3 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:7)

类似文件的输入/输出与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磁盘,可以在操作系统级别更好地解决此类问题。有了它,你甚至可以调用外部程序重定向他们的输出或从这些文件输入,你也得到所有的全面支持,包括并发访问,目录列表等。

答案 2 :(得分: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