Python добавляет несколько файлов в указанном порядке в один большой файл - PullRequest
13 голосов
/ 01 апреля 2011

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

Ответы [ 8 ]

26 голосов
/ 01 апреля 2011

Просто с помощью простого файлового ввода-вывода:

# 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())

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

8 голосов
/ 01 апреля 2011

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

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

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

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

# 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

Урок ввода / вывода учебник содержит много полезной информации.

6 голосов
/ 16 августа 2013

В ответе Рэйфа отсутствовали правильные операторы открытия / закрытия, например,

# 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, что приведет к странным результатам сортировки.В этом случае вам нужно будет обрезать строки временного файла по мере их чтения, а затем записывать согласованные строки EOL в большой файл (т. Е. С использованием дополнительной строки кода).

3 голосов
/ 16 марта 2017
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.

1 голос
/ 11 октября 2014

Попробуй это. Это очень быстро (намного быстрее, чем построчно, и не должно вызывать трэш виртуальной машины для больших файлов), и должно работать почти на всем, включая 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 сигналов.

1 голос
/ 11 октября 2014

Использовать 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.

0 голосов
/ 08 октября 2018

Простой и эффективный способ копирования данных из нескольких файлов в один большой файл. Перед этим вам нужно переименовать ваши файлы в (int), например 1,2,3,4 ... и т. Д., Код:

#Rename Files First

import os

path = 'directory_name'
files = os.listdir(path)
i = 1
for file in files:
    os.rename(os.path.join(path, file), os.path.join(path, str(i)+'.txt'))

    i = i+1

# Code For Copying Data from Multiple files

import os

i = 1
while i<50:

    filename = i
    for filename in os.listdir("directory_name"):

        # %s is your filename # .txt is file extension 
        f = open("%s.txt" % i,'r') 
        fout = open("output_filename", "a")

    for line in f:
        fout.write(line)
    i += 1
0 голосов
/ 11 сентября 2018

В этом коде вы можете указать путь и имя файлов ввода / вывода, и он создаст окончательный большой файл по этому пути:

import os

dir_name = "Your_Desired_Folder/Goes_Here"    #path
input_files_names = ["File1.txt", "File2.txt", "File3.txt"]     #input files
file_name_out = "Big_File.txt"     #choose a name for the output file
file_output = os.path.join(dir_name, file_name_out)
fout = open(file_output, "w")

for tempfile in input_files_names:
    inputfile = os.path.join(dir_name, tempfile)
    fin = open(inputfile, 'r')
    for line in fin:
        fout.write(line)

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