如何修改Python按字节分割大文件的代码以保留行完整性?
可以实现,修改方案如下
核心思路
不再严格按固定字节数分割,而是在接近设定的分割大小时,继续读取直到找到行尾换行符,确保每个子文件的最后一行完整;同时处理文件末尾的边界情况,以及单行超过分割大小的极端场景。
修改后的完整代码
import os import sys def splitfile(spath, sfilename, splitsize, dpath): full_input_path = os.path.join(spath, sfilename) if not os.path.isfile(full_input_path): print(f"文件不存在: {full_input_path}") return # 自动创建输出目录(如果不存在) os.makedirs(dpath, exist_ok=True) # 分离文件名和后缀,避免多后缀文件名出错 base_name, ext = os.path.splitext(sfilename) counter = 1 with open(full_input_path, "rb") as fr: while True: buffer = b"" bytes_written = 0 # 按4KB块读取,兼顾效率和换行查找精度 while bytes_written < splitsize: chunk = fr.read(4096) if not chunk: break # 文件读取完毕 # 检查添加当前块是否会超出分割大小 if bytes_written + len(chunk) > splitsize: # 从当前块中找最后一个换行符的位置 newline_pos = chunk.rfind(b"\n") if newline_pos != -1: # 读取到换行符为止,剩余内容放回文件指针 buffer += chunk[:newline_pos+1] bytes_written += newline_pos + 1 fr.seek(fr.tell() - (len(chunk) - newline_pos - 1)) else: # 单行超过分割大小,直接保留整行 buffer += chunk bytes_written += len(chunk) else: buffer += chunk bytes_written += len(chunk) if not buffer: break # 无数据可写,退出循环 # 生成带三位数字序号的子文件名 output_filename = f"{base_name}_{counter:03d}{ext}" full_output_path = os.path.join(dpath, output_filename) # 写入子文件 with open(full_output_path, "wb") as fw: fw.write(buffer) print(f"已生成子文件: {full_output_path}") counter += 1 if __name__ == "__main__": if len(sys.argv) < 5: print("使用方法: filesplit.py <输入文件路径> <输入文件名> <分割大小(KB)> <输出目录>") print("示例: filesplit.py ./ data.txt 102400 ./split_files") sys.exit(1) try: spath = sys.argv[1] sfilename = sys.argv[2] splitsize_kb = int(sys.argv[3]) dpath = sys.argv[4] # 标准KB转字节(1KB=1024字节) splitsize = splitsize_kb * 1024 splitfile(spath, sfilename, splitsize, dpath) except ValueError: print("分割大小必须是整数") sys.exit(1)
关键修改说明
- 文件名处理优化:用
os.path.splitext替代split("."),避免文件名含多个点时出错;用{counter:03d}生成三位数字序号,符合需求中的filename_001.txt格式。 - 读取逻辑重构:
- 采用4KB块读取,兼顾效率和换行查找的精度
- 当即将超出分割大小时,查找当前块内的最后一个换行符,只读取到换行符位置,剩余内容放回文件指针留给下一个子文件
- 处理单行超过分割大小的极端情况,确保整行完整保留
- 参数修正:
- 修复原代码命令行参数顺序错误的问题,明确参数含义
- 用标准的
1024将KB转换为字节(原代码用1000不符合单位定义) - 增加参数错误提示和异常捕获
- 冗余代码移除:删除不必要的
getfilesize函数,直接循环读取直到文件结束,逻辑更灵活 - 输出目录处理:自动创建输出目录,避免因目录不存在导致报错
内容的提问来源于stack exchange,提问作者rob
相关产品推荐
相关产品推荐

