我正在尝试在Python 3中找到一种方法,该方法将接受作为输入提供的任何文件,并从原始文件创建4个较小的文件。就字符数而言,四个较小的文件的长度必须彼此相似。如果无法根据文本文件中的字符数执行此操作,是否可以按字节将其拆分,但是如果文本文件的大小更改,它仍然可以工作吗?
作为测试文件,我只是重复使用了几次字母。这完全按照需要工作。在具有多台服务器的对等文件共享系统中使用此功能。给定的文件应该分成4个较小的文件,每个文件都将放置在两个服务器上,这样,如果出现任何问题,仍然可以进行备份。
答案 0 :(得分:1)
(在2018年)文本文件通常经过UTF-8编码。请注意,许多人不会说英语或说英语,可能会使用其他人类语言和“字符”(包括smileys)。阅读utf8everywhere.org了解更多。而且,如果它不是UTF-8编码的,则您需要了解(通过其他方式)或决定使用确切的character encoding。
在UTF-8中,许多Unicode字符(例如§
或é
或Ж
或λ
或㜼
或א
或ح
,∈
,等...)需要几个字节进行编码。因此,您不能在任意字节边界处分割UTF-8编码的文本文件,而应在unicode字符的末尾分割它。
作为测试文件,我只是重复使用几次字母
那太天真了。您应该使用还包含奇怪字符(例如希腊语,阿拉伯语,西里尔字母,汉字或 是否可以按字节分解 否,如果它是UTF-8编码的(因为正如我所解释,原始文件的某些Unicode字符可能需要几个字节)。如果您将一个Unicode字符拆分为“在中间”几个字节,则结果通常不符合UTF-8(例如 但是如果文本文件的大小更改了,它仍然可以工作吗? 如果原始源文件发生更改,则需要再次对其进行处理,以将其再次分成较小的块。如何检测原始源文件何时已更改是另一个问题(在Linux上,在某些情况下,您可能使用inotify(7)工具来检测此类更改)。许多operating systems和file systems保留修改时间(例如POSIX系统上 您可能希望将文本文件分成整条行的块(因此不要在任意字节边界)。为此,您可以在Linux上使用split(1)(可以在Linux上使用wc(1)和 当然,您可以轻松地在Python中编写一个函数,该函数计算文本文件中的行数,而另一个函数则将其分成整行,因为Python具有便利性(例如,{{∀
或笑脸等数学符号)的文件来测试解决方案,而不仅仅是英语字母。< / p>
é
是由两个字节 0xc3
0xa9
以十六进制表示,但 0xc3
不会 not 编码 valid UTF-隔离8个字符)
st_mtime
赋予的stat(2)),您可以使用它来触发拆分。当然,详细信息是操作系统专用。-l
来计算行数)。readline
}函数{3}})来阅读整行。或者,您可以像io一样,将文件拆分成大约相等的字符长度的块,这不是不是个字节的长度(正如您的问题明确要求的:“按字节分解”) )。
答案 1 :(得分:0)
我认为通过字符计数是可行的(在UTF-8编码中,一个字符可能会占用一个以上的字节)。我们可以将其分解为两个问题:
我已经在下面的简单ASCII文件和UTF-8示例文件中测试了以下代码:https://www.w3.org/2001/06/utf-8-test/UTF-8-demo.html
文本文件的一个小示例将帮助人们了解您的问题。
编辑:添加了逻辑以处理字符计数不能被拆分/段计数整除的情况。
import os
def split_file(in_file_name, split_count):
"""Splits the input file into a specified number of segments."""
with open(in_file_name, 'r') as in_file:
# Get a count of characters in the file.
character_count = 0
for line in in_file:
for character in line:
character_count = character_count + 1
size_per_out_file = character_count / split_count
# Split up the input file into chunks/segments.
in_file.seek(0)
for i in range(0, split_count):
if (i == (split_count - 1)):
current_out_content = in_file.read(size_per_out_file + split_count)
else:
current_out_content = in_file.read(size_per_out_file)
out_file_name = '%s_segment_%d.txt' % (in_file_name, i)
with open(out_file_name, 'w') as current_out_file:
current_out_file.write(current_out_content)
if __name__ == "__main__":
split_file("in_file.txt", 4)