как избежать создания фиктивного файла, чтобы получить ссылку на файл - PullRequest
0 голосов
/ 30 марта 2019

Я хочу разделить файл на несколько других файлов. Мой код ниже работает, мне только интересно, есть ли лучший способ сделать это. Я создаю фиктивный файл 'dummy.bin', чтобы получить ссылку на файл fw. В первой итерации цикла while вызывается функция fw.close (), поэтому мне нужна ссылка на этот файл. После того, как файл прочитан до конца, я снова удаляю фиктивный файл. У меня вопрос: нужно ли создавать этот фиктивный файл, чтобы получить ссылку на файл, или есть другой, более элегантный способ сделать это? Мне кажется немного глупым создавать файл и удалять его снова, чтобы получить ссылку на файл. (count просто считает от 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 голосов
/ 30 марта 2019

Давайте посмотрим, что вы хотите сделать.

  1. Разбить some_file.bin на поток по 512 байт.
  2. Запишите по 100 блоков в каждый из выходных файлов.

Сто 512-байтовых блоков эквивалентны одному фрагменту размером 51 200 байт. Так что давайте поработаем с ними.

Мы будем использовать enumerate для получения увеличивающегося количества чанков вместо того, чтобы поддерживать его сами.

Наконец, используйте форму с двумя аргументами iter для создания последовательности фрагментов длиной 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 для выхода (идиома Python для do-while циклов).

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()
0 голосов
/ 30 марта 2019

Вы можете использовать tempfile.TemporaryFile для вашего фиктивного файла.https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryFile

В частности, это может даже не создать файл на диске.И в любом случае он будет убирать за собой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...