Python将多个文件按给定顺序附加到一个大文件中

Python将多个文件按给定顺序附加到一个大文件中,python,file,append,Python,File,Append,我有多达8个单独的Python进程在共享文件夹中创建临时文件。然后我希望控制过程将所有临时文件按一定顺序附加到一个大文件中。在与操作系统无关的shell级别上,最快的方法是什么?仅使用简单的文件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.w

我有多达8个单独的Python进程在共享文件夹中创建临时文件。然后我希望控制过程将所有临时文件按一定顺序附加到一个大文件中。在与操作系统无关的shell级别上,最快的方法是什么?

仅使用简单的文件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())

这与操作系统无关。它也相当简单,性能应该和使用其他任何东西一样好。

不知道任何用于将一个文件附加到另一个文件的shell级别命令。但是在“python级别”进行附加非常容易,我猜python开发人员认为没有必要将其添加到库中

解决方案取决于要附加的临时文件的大小和结构。如果它们都足够小,以至于你不介意将它们读入内存,那么Rafe Ketterr的答案(从他的答案中复制,并在下面重复)将以最少的代码完成这项工作

# 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

输入/输出有很多好的信息。

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())
但是,需要预先警告的是,如果要对bigfile的内容进行排序,此方法不会捕获一个或多个temp文件中最后一行具有不同EOL格式的实例,这将导致一些奇怪的排序结果。在这种情况下,您需要在读取tempfile行时剥离它们,然后将一致的EOL行写入bigfile(即,涉及一行额外的代码)。

使用:

这比@RafeKettler的答案更节省内存,因为在写入
大文件之前,不需要将整个文件读入内存。它非常快(比逐行的速度快得多,并且不会对大文件造成VM冲击),应该可以运行任何东西,包括cpython2.x、cpython3.x、pypypy、Pypy3和Jython。而且它应该是高度不可知操作系统的。此外,它对文件编码没有任何假设

#!/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信号时才真正需要这样做

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文件中。

在此代码中,您可以指示输入/输出文件的路径和名称,它将在该路径中创建最终的大文件:

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

将数据从多个文件复制到一个大文件的简单高效方法,在此之前,您需要将文件重命名为(int),例如1、2、3、4…等,代码:

#首先重命名文件
导入操作系统
路径='目录\名称'
files=os.listdir(路径)
i=1
对于文件中的文件:
重命名(os.path.join(路径,文件),os.path.join(路径,str(i)+'.txt'))

i=i+1
Python3中还有fileinput类,非常适合这种情况

在8年后添加另一个答案和这么多答案后,我觉得有点愚蠢,但我是以“附加到文件”的标题来到这里的,并且没有看到使用缓冲读/写来附加到现有二进制文件的正确解决方案

下面是实现这一点的基本方法:

def append_file_to_file(_from, _to):
    block_size = 1024*1024
    with open(_to, "ab") as outfile, open(_from, "rb") as infile:
        while True:
            input_block = infile.read(block_size)
            if not input_block:
                break
            outfile.write(input_block)
鉴于此构造块,您可以使用:

for filename in ['a.bin','b.bin','c.bin']:
    append_file_to_file(filename, 'outfile.bin')

是否要使用shell命令执行此操作?文件IO是否正常?使用f.write(tempfile.read())比其他复制方式稍微快一点。f.write(tempfile.read())对于小文件来说可能很快,但对于大文件来说却很糟糕。只有当每个文件都足够小,可以读入内存时,才可能进行复制。如果您可以并行读写(例如,不同的磁盘或体系结构允许并行读写),那么性能也会更差,因为您将在开始任何操作之前等待文件被读取。您可能会更好地使用shutil.copyfileobjPerhaps应该使用二进制I/O。如果您想知道什么时候一个解决方案更合适,一个文件在
f.write(tempfile.read())
变得不合适之前使用了多少内存,那就好了,如果您添加一个关于如何使用fileinput的示例
for filename in ['a.bin','b.bin','c.bin']:
    append_file_to_file(filename, 'outfile.bin')