如何避免创建虚拟文件以获得文件参考

时间:2019-03-30 15:27:09

标签: python file

我想将一个文件分割成其他几个文件。我下面的代码有效,我只想知道是否有更好的方法可以做到这一点。我创建了一个虚拟文件'dummy.bin'以获取文件引用fw。在我的while循环的第一次迭代中,调用了fw.close(),因此这就是为什么我需要在这里引用该文件的原因。读取完文件后,我再次删除虚拟文件。我的问题是:我是否必须创建此虚拟文件才能获得文件引用,或者是否有另一种更优雅的方式来做到这一点?创建文件然后再次删除它以获取文件引用对我来说似乎有点愚蠢。 (计数范围从0到99,因此每100个连续的块都被写入另一个文件)

import os

chunk_size = 512
count = 0
i = 0

f = open('some_file.bin', 'rb')
chunk = f.read(chunk_size)

fw = open('dummy.bin', 'wb')

while chunk:
    if count is 0:
        fw.close()
        filename = 'part_' + str(i) + '.bin'
        i += 1
        fw = open(filename, 'wb')
    fw.write(chunk)
    count = (count + 1) % 100
    chunk = f.read(chunk_size)
fw.close()
f.close()
os.remove('dummy.bin')

2 个答案:

答案 0 :(得分:0)

您可以将tempfile.TemporaryFile用于虚拟文件。 https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryFile

尤其是,这甚至可能实际上并未在磁盘上创建文件。而且无论如何,它都会自行清理。

答案 1 :(得分:0)

让我们看看你想做什么。

  1. some_file.bin分成512字节的块流。
  2. 将100个块写入一系列输出文件中的每个。

一百个512字节的块相当于一个51,200字节的块。因此,让我们改为使用它们。

我们将使用enumerate来获取增加的块数,而不是自己维护。

最后,使用iter的2个参数形式从输入文件创建一个51,200字节块的序列。

完全放在一起

chunk_size = 51200

with open('some_file.bin', 'rb') as f:
    def read_chunk():
        return f.read(chunk_size)

    chunks = iter(read_chunk, '')

    for i, chunk in enumerate(chunks):
        outfile = "part_{}.bin".format(i)
        with open(outfile, 'wb') as out:
             out.write(chunk)

现在,在准备好实际写东西之前,我们实际上并没有打开要写入的文件。


对于您的原始代码,您需要打开一个虚拟文件这一事实仅意味着您正在检查是否应该在错误的位置关闭该文件。您知道要写入的第一个文件是part_0.bin,因此您应该可以首先打开该文件。

import os

chunk_size = 512
count = 0
i = 0

f = open('some_file.bin', 'rb')
chunk = f.read(chunk_size)

fw = open('part_0.bin', 'wb')

while chunk:
    if count == 100:
        count = 0
        fw.close()
        i = i + 1
        fw = open("part_{}.bin".format(i)
    fw.write(chunk)
    count += 1
    chunk = f.read(chunk_size)
fw.close()
f.close()

您仍然可以对此进行重构。至少,您可以使用with语句打开输入文件。如果您通过一个明确的f.read语句退出而使之成为无限循环,则也可以将对while的调用移到break循环中(do-while循环的Python习惯用法)

import os

chunk_size = 512
count = 0
i = 0

with open('some_file.bin', 'rb') as f:
    fw = open('part_0.bin', 'wb')
    while True:
        chunk = f.read(chunk_size)
        if not chunk:
            break
        if count == 100:
            count = 0
            fw.close()
            i = i + 1
            fw = open("part_{}.bin".format(i)
        fw.write(chunk)
        count += 1
    fw.close()