如何进行虚拟文件处理?


70

因此,对于创建文件,我使用以下命令:

fileHandle = open('fileName', 'w')

然后将内容写入文件,关闭文件。在下一步中,我处理文件。在程序的最后,我得到一个需要删除的“物理文件”。

有没有一种方法可以编写行为与“物理”文件完全一样的“虚拟”文件(允许以相同的方式对其进行操作),但是在运行Python时却不存在该文件?

Answers:


70

您可能要考虑使用a tempfile.SpooledTemporaryFile,它可以为您提供两全其美的感觉,因为它将最初创建一个基于内存的临时虚拟文件,但是如果保存在内存中的数据超过指定的数量,它将自动切换到基于物理磁盘的文件尺寸。

另一个不错的功能是(使用内存时)它将自动使用io.BytesIO或,io.StringIO具体取决于mode所使用的内容-允许您对其读写Unicode字符串或二进制数据(字节)。

唯一棘手的部分可能是您需要避免在步骤之间关闭文件,因为这样做可能会导致文件从内存或磁盘中删除。相反,您可以使用文件seek(0)方法调用将其倒回至开头。

当您完成文件的处理并关闭它后,如果其中的数据量过多,则会自动将其从磁盘中删除,并将其移到物理文件中。



2
来自另一个问题,值得注意的是,此临时内存文件没有文件名(需要在处理程序上进行操作)。该解决方案非常适合OP使用(+1)。什么模块中不幸缺少的是tempfile.NamedSpooledTemporaryFile()(组合NamedTemporaryFile()SpooledTemporaryFile()
WoJ

@WoJ:感谢+1。我认为没有原因tempfile.NamedSpooledTemporaryFile()是因为说可以保证基于内存的虚拟文件开头的文件在文件系统中具有可见的名称是没有意义的,尽管在某些情况下它可能只有一个可见的名称大小超过指定的max_size阈值。tempfile模块的源代码位于中python/Lib/tempfile.py,如果您想以所需的行为自己实现某件事(无论当前数据在内存中是什么),这可能会有所帮助。
martineau '18年

53

你有StringIOBytesIOio模块。

StringIO行为类似于在文本模式下打开的文件-读写unicode字符串(相当于使用来打开文件io.open(filename, mode, encoding='...')),BytesIO行为类似于以二进制模式(mode='[rw]b')打开的文件,并且可以读取写入字节。

Python 2:

In [4]: f = io.BytesIO('test')
In [5]: type(f.read())
Out[5]: str
In [6]: f = io.StringIO(u'test')
In [7]: type(f.read())
Out[7]: unicode

Python 3:

In [2]: f = io.BytesIO(b'test')
In [3]: type(f.read())
Out[3]: builtins.bytes
In [4]: f = io.StringIO('test')
In [5]: type(f.read())
Out[5]: builtins.str


13

您可以从官方文档中将StringIO用作虚拟文件

from io import StringIO

output = 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()

10
请记住,如果要将其作为文件状对象传递给另一个函数,则应使用以下命令回绕虚拟文件:output.seek(0)
RufusVS 2014年

1
男人,您是从官方文档中复制粘贴吗?:)我认为在这种情况下使用链接是公平的。
maxadamo

@maxadamo完成。谢谢。
斯里尼瓦斯·雷迪·撒提帕西'17

2
from io import StringIO对于python> = 3
Christof18,2018年

0

StringIO模块,阅读其文档,应该易于使用。

但是请记住,这会将“文件”的内容保留在内存中。如果数据太多,最好在/ tmp中创建一个真实文件,然后再删除它。


0

如果您要写入内存而不是文件,则只需将文本写入缓冲区并使用以下功能:

def write(text):
  global buffer
  buffer += text + '\n'  # Add a linefeed as you would if you were writing to a file

buffer = ""  # Initialize the buffer
write("My name is Steve Grafton")

最后,您将拥有一个缓冲区,该缓冲区与将内容写入文件然后打开该文件并将其所有内容读取到缓冲区一样!此外,您可以在处理过程中使用缓冲区(在完成写入之前)并在其中进行搜索,就好像您已经创建了用于读取和写入的文件一样,只有在这种情况下,指针才会

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.