Python如何将大TXT文件分割成4KB小文件!
Python如何将大TXT文件分割成4KB小文件!
处理大文本文件是程序员经常遇到的挑战。特别是当我们需要把一个几百MB甚至几个GB的TXT文件分割成小块时,手动操作显然不现实。今天我们就来聊聊如何用Python自动完成这个任务,特别是如何精确控制每个分割文件的大小为4KB。
为什么需要分割TXT文件
在实际开发中,我们可能会遇到这些情况:
- 某些老旧系统只能处理小体积文本文件
- 需要将日志文件分割后上传到云存储
- 进行分布式处理时需要将数据分片
- 调试时需要用小文件快速测试
4KB是个很常用的分割尺寸,因为它正好是很多系统默认的内存页大小,处理起来效率很高。那么问题来了:怎么用Python实现这个需求呢?
基础版:按行分割
我们先来看一个最简单的实现方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
def split_by_line(input_file, output_prefix, chunk_size = 4000 ): with open (input_file, 'r' , encoding = 'utf-8' ) as f: file_count = 1 current_size = 0 output_file = None for line in f: line_size = len (line.encode( 'utf-8' )) if current_size + line_size > chunk_size: if output_file: output_file.close() output_file = open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) file_count + = 1 current_size = 0 if not output_file: output_file = open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) file_count + = 1 output_file.write(line) current_size + = line_size if output_file: output_file.close() |
这个脚本可以按行分割文件,尽量保证每个文件不超过指定大小。但是有个问题:它不能精确控制文件大小正好是4KB,特别是当某一行特别长时,单个文件可能会超过限制。
进阶版:精确控制文件大小
要实现更精确的控制,我们需要按字节而不是按行来处理:
1
2
3
4
5
6
7
8
9
10
|
def split_by_size(input_file, output_prefix, chunk_size = 4096 ): with open (input_file, 'rb' ) as f: file_count = 1 while True : chunk = f.read(chunk_size) if not chunk: break with open (f "{output_prefix}_{file_count}.txt" , 'wb' ) as out_file: out_file.write(chunk) file_count + = 1 |
注意! 这里我们用二进制模式(‘rb’)打开文件,这样可以精确控制读取的字节数。但是这样可能会在UTF-8编码的中文文件中出现乱码,因为一个中文字符可能被从中间截断。
完美解决方案:支持UTF-8编码
为了解决中文乱码问题,我们需要更智能的处理方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
def split_utf8_safely(input_file, output_prefix, chunk_size = 4096 ): buffer = "" file_count = 1 current_size = 0 with open (input_file, 'r' , encoding = 'utf-8' ) as f: while True : char = f.read( 1 ) if not char: if buffer : with open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) as out_file: out_file.write( buffer ) break char_size = len (char.encode( 'utf-8' )) if current_size + char_size > chunk_size: with open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) as out_file: out_file.write( buffer ) file_count + = 1 buffer = "" current_size = 0 buffer + = char current_size + = char_size |
这个方法逐个字符读取文件,确保不会截断多字节字符。虽然速度会慢一些,但能保证分割后的文件都能正常显示中文内容。
性能优化:使用缓冲区
处理大文件时,逐个字符读取效率太低。我们可以用缓冲区来提升性能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
def split_with_buffer(input_file, output_prefix, chunk_size = 4096 , buffer_size = 1024 ): buffer = "" file_count = 1 current_size = 0 with open (input_file, 'r' , encoding = 'utf-8' ) as f: while True : chunk = f.read(buffer_size) if not chunk: if buffer : with open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) as out_file: out_file.write( buffer ) break buffer + = chunk while len ( buffer .encode( 'utf-8' )) > = chunk_size: # 找到不超过chunk_size的最大子串 split_pos = 0 for i in range ( 1 , len ( buffer ) + 1 ): if len ( buffer [:i].encode( 'utf-8' )) < = chunk_size: split_pos = i else : break with open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) as out_file: out_file.write( buffer [:split_pos]) file_count + = 1 buffer = buffer [split_pos:] current_size = 0 |
处理特殊情况
实际应用中我们还需要考虑一些特殊情况:
- 文件头处理:如果需要保留原文件的头信息到每个分割文件
- 行完整性:某些场景下需要保持行的完整性
- 内存限制:处理超大文件时的内存优化
- 进度显示:添加进度条让长时间运行的任务更友好
这里给出一个保留文件头的实现示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
def split_with_header(input_file, output_prefix, chunk_size = 4096 , header_lines = 1 ): # 先读取文件头 with open (input_file, 'r' , encoding = 'utf-8' ) as f: header = [ next (f) for _ in range (header_lines)] buffer = "" file_count = 1 current_size = len (' '.join(header).encode(' utf - 8 ')) with open (input_file, 'r' , encoding = 'utf-8' ) as f: # 跳过已经读取的文件头 for _ in range (header_lines): next (f) while True : char = f.read( 1 ) if not char: if buffer : with open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) as out_file: out_file.writelines(header) out_file.write( buffer ) break char_size = len (char.encode( 'utf-8' )) if current_size + char_size > chunk_size: with open (f "{output_prefix}_{file_count}.txt" , 'w' , encoding = 'utf-8' ) as out_file: out_file.writelines(header) out_file.write( buffer ) file_count + = 1 buffer = "" current_size = len (' '.join(header).encode(' utf - 8 ')) buffer + = char current_size + = char_size |
总结
我们介绍了多种Python分割TXT文件的方法:
简单的按行分割适合行结构明显的文件
按字节分割效率最高但不支持UTF-8
带UTF-8支持的版本适合中文文本
缓冲区的版本在性能和准确性之间取得平衡
特殊需求如保留文件头需要额外处理
记住! 选择哪种方法取决于你的具体需求。如果是处理GB级别的大文件,建议使用缓冲区方案并考虑内存映射等高级技术。希望这篇指南能帮你解决文件分割的问题!
到此这篇关于Python如何将大TXT文件分割成4KB小文件的文章就介绍到这了。
学习资料见知识星球。
以上就是今天要分享的技巧,你学会了吗?若有什么问题,欢迎在下方留言。
快来试试吧,小琥 my21ke007。获取 1000个免费 Excel模板福利!
更多技巧, www.excelbook.cn
欢迎 加入 零售创新 知识星球,知识星球主要以数据分析、报告分享、数据工具讨论为主;
1、价值上万元的专业的PPT报告模板。
2、专业案例分析和解读笔记。
3、实用的Excel、Word、PPT技巧。
4、VIP讨论群,共享资源。
5、优惠的会员商品。
6、一次付费只需129元,即可下载本站文章涉及的文件和软件。
共有 0 条评论