split按行或字节切分最快,但需注意行数默认1000、中文编码、后缀排序;python用itertools.islice流式处理更跨平台可控;按mb切分须保证行完整;切分后务必校验md5或行数。

用 split 命令按行数切分最简单,但注意换行符和编码
Linux/macOS 自带的 split 是最快捷的方案,Windows 用户需装 Git Bash 或 WSL 才能直接用。它不读取文件内容,纯按字节或行计数,所以快、内存占用低。
常见错误是默认按 1000 行切,结果最后一块只有几行;或者文件含中文却没指定 --verbose 和编码环境,导致切出来的文件名乱码(实际内容没事)。
-
split -l 50000 big.log chunk_:每 5 万行一个文件,前缀为chunk_ -
split -l 50000 -d big.log chunk_:加-d用数字后缀(chunk_00),比默认字母更易排序 - 若文件是 UTF-8 with BOM 或 GBK,
split不处理编码,但后续用 Python 读时得显式指定encoding,否则UnicodeDecodeError
Python 里用 itertools.islice 按行切分,避免全加载
想跨平台、可控编码、或需预处理(比如跳过 header、过滤空行),就得写 Python。关键不是“怎么读”,而是“别一次性 readlines()”——大文件会 OOM。
itertools.islice 是标准库里最轻量的流式切片工具,配合 open(..., buffering=8192) 控制缓冲区,能稳住内存。
- 每次打开源文件一次,用
islice(f, chunk_size)取固定行,再写入新文件 - 务必用
with open(...)包裹每个子文件写入,否则可能丢失最后一点数据(缓冲未刷) - 不要用
enumerate+%判断行号——累计计数在超大文件下有整数溢出风险(虽罕见,但islice更稳) - 示例片段:
from itertools import islice<br>with open('big.csv', encoding='utf-8') as f:<br> for i in range(0, total_lines, 10000):<br> chunk = list(islice(f, 10000))<br> with open(f'part_{i//10000}.csv', 'w', encoding='utf-8') as out:<br> out.writelines(chunk)
按 MB 大小切分必须自己算字节边界,不能依赖行数
日志或二进制数据常要求“每个块 ≤ 50MB”,这时行数切分完全失效。核心难点在于:不能截断单行(否则 CSV 解析失败)、也不能把一行硬拆成两半。
做法是边读边累加字节数,每接近目标大小时,先读完当前行再切,这样每块结尾都是完整行。缺点是无法精确到字节(总有几 KB 浮动),但业务上可接受。
- 用
f.read(8192)分块读,比逐行for line in f更可控字节数 - 遇到换行符
\n或\r\n才判断是否达到阈值,否则继续攒 - Windows 换行符是
\r\n(2 字节),Linux 是\n(1 字节),用os.linesep不可靠——得按实际文件检测 - 特别注意:UTF-8 中文字符占 3 字节,
len(line.encode('utf-8'))才是真实写入字节数,别用len(line)
切分后校验完整性容易被忽略,尤其跨平台传输
切完只是开始。用户真正卡住的地方往往是:合并回原文件后 MD5 不一致、某块少了几行、或最后块末尾多了空行。
原因很实在——文本模式写入自动补换行、不同系统行尾差异、split 的 -a 参数控制后缀长度不够导致覆盖、甚至 NFS 挂载点缓存延迟造成 ls 看到文件但 cat 报空。
- 切分前先算总行数:
wc -l big.log | awk '{print $1}',切完用wc -l chunk_* | tail -1对比 - 二进制校验用
sha256sum,文本校验建议用md5sum(兼容旧系统),别只比文件大小 - Python 写入时加
newline=''参数,禁用 universal newlines,避免额外转换 - 如果目标是上传 S3 或 HDFS,优先用
split -b(按字节)+--filter配合gzip,比 Python 更稳
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











