Python добавляет несколько файлов в заданном порядке в один большой файл

У меня есть до 8 отдельных процессов Python, создающих временные файлы в общей папке. Затем я хочу, чтобы процесс управления добавлял все временные файлы в определенном порядке в один большой файл. Какой самый быстрый способ сделать это на уровне агностической оболочки os?

Ответ 1

Просто используя простой файл IO:

# tempfiles is a list of file handles to your temp files. Order them however you like
f = open("bigfile.txt", "w")
for tempfile in tempfiles:
    f.write(tempfile.read())

Это примерно так же как агностик. Это также довольно просто, и производительность должна быть примерно такой же, как и при использовании чего-либо еще.

Ответ 2

Не известно о каких-либо командах на уровне оболочки для добавления одного файла в другой. Но добавление на уровне "python" достаточно просто, что я предполагаю, что разработчики python не считают необходимым добавлять его в библиотеку.

Решение зависит от размера и структуры файлов temp, которые вы добавляете. Если они все достаточно малы, чтобы вы не читали каждую из них в памяти, то ответ Райфа Кеттлера (скопированный из его ответа и повторенного ниже) выполняет работу с наименьшим количеством кода.

# tempfiles is an ordered list of temp files (open for reading)
f = open("bigfile.txt", "w")
for tempfile in tempfiles:
    f.write(tempfile.read())

Если чтение файлов полностью в память невозможно или не подходит для решения, вам нужно будет пропустить каждый файл и прочитать его по кусочкам. Если ваш файл temp содержит строки с завершающим расширением строки, которые можно прочитать отдельно в памяти, вы можете сделать что-то вроде этого

# tempfiles is an ordered list of temp files (open for reading)
f = open("bigfile.txt", "w")
for tempfile in tempfiles:
    for line in tempfile
        f.write(line)

Альтернативно - что-то, что всегда будет работать - вы можете выбрать размер буфера и просто прочитать фрагмент файла, например.

# tempfiles is an ordered list of temp files (open for reading)
f = open("bigfile.txt", "w")
for tempfile in tempfiles:
    while True:
        data = tempfile.read(65536)
        if data:
            f.write(data)
        else:
            break

Ввод/вывод tutorial содержит много полезной информации.

Ответ 3

В ответе Rafe отсутствовали правильные инструкции открытия/закрытия, например

# tempfiles is a list of file handles to your temp files. Order them however you like
with open("bigfile.txt", "w") as fo:
     for tempfile in tempfiles:
          with open(tempfile,'r') as fi: fo.write(fi.read())

Однако следует предупредить, что если вы хотите отсортировать содержимое большого файла, этот метод не будет проверять случаи, когда последняя строка в одном или нескольких ваших временных файлах имеет другой формат EOL, что приведет к некоторым странным результатам сортировки, В этом случае вам нужно будет стричь строки tempfile по мере их чтения, а затем записать согласованные строки EOL в файл bigfile (т.е. Включить дополнительную строку кода).

Ответ 4

Используйте fileinput:

with open("bigfile.txt", "w") as big_file:
    with fileinput.input(files=tempfiles) as inputs:
        for line in inputs:
            big_file.write(line)

Это более эффективная память, чем ответ @RafeKettler, так как ему не нужно читать весь файл в памяти, прежде чем писать в big_file.

Ответ 5

Попробуйте это. Это очень быстро (намного быстрее, чем строка за строкой, и не должно вызывать трэш файл для больших файлов), и должно работать на чем угодно, включая CPython 2.x, CPython 3.x, Pypy, Pypy3 и Jython. Также он должен быть сильно OS-агностиком. Кроме того, он не делает никаких предположений о кодировании файлов.

#!/usr/local/cpython-3.4/bin/python3

'''Cat 3 files to one: example code'''

import os

def main():
    '''Main function'''
    input_filenames = ['a', 'b', 'c']

    block_size = 1024 * 1024

    if hasattr(os, 'O_BINARY'):
        o_binary = getattr(os, 'O_BINARY')
    else:
        o_binary = 0
    output_file = os.open('output-file', os.O_WRONLY | o_binary)
    for input_filename in input_filenames:
        input_file = os.open(input_filename, os.O_RDONLY | o_binary)
        while True:
            input_block = os.read(input_file, block_size)
            if not input_block:
                break
            os.write(output_file, input_block)
        os.close(input_file)
    os.close(output_file)

main()

Существует одна (нетривиальная) оптимизация, о которой я не упоминал: лучше не принимать ничего о хорошем блоке, вместо этого использовать кучу случайных и медленно отступать от рандомизации, чтобы сосредоточиться на хороших (иногда называемых "имитация отжига" ). Но это намного сложнее для небольшой фактической производительности.

Вы также можете заставить os.write отслеживать возвращаемое значение и перезапустить частичную запись, но это действительно необходимо, если вы ожидаете получать (нетерминальные) * ix сигналы.

Ответ 6

import os
str = os.listdir("./")

for i in str:
    f = open(i)
    f2 = open("temp.txt", "a")
    for line in f.readlines():
        f2.write(line)

Мы можем использовать вышеприведенный код, чтобы прочитать все содержимое из всего файла, присутствующего в текущем каталоге, и сохранить его в файле temp.txt.