大文件分片合并必须流式串行搬运,唯一安全方式是io.Copy;需用os.Create创建目标文件、按数字排序分片、合并前后校验SHA256。

大文件分片合并不能靠“攒完再拼”,必须流式串行搬运,否则一合并就 OOM 或 PDF 打不开。
io.Copy 是唯一安全的合并方式
别碰 os.ReadFile、io.ReadAll、bytes.Buffer——它们会把所有分片全读进内存。GB 级文件合并失败,90% 源于此。
-
io.Copy默认用 32KB 缓冲区,只搬字节流,内存恒定几 KB - 目标文件必须用
os.Create(dstPath),不是os.OpenFile(..., os.O_APPEND):后者首次创建时看似能写,但逻辑混乱,易残留旧内容 - 每个分片用
os.Open(srcPath)直传给io.Copy,中间不经过任何[]byte中转 - 若需微调缓冲区,才用
io.CopyBuffer包一层,普通场景无需
分片文件名排序必须按数字,不是字符串
filepath.Glob("part_*") 返回 part_1、part_10、part_2 是正常行为,但按这顺序合并,数据必然错位。
- 生成分片时强制零填充:
fmt.Sprintf("part_%03d", i)→part_001、part_002 - 读取前显式提取数字再排序:
sort.Slice(files, func(i, j int) bool { return extractNum(files[i]) < extractNum(files[j]) }) -
extractNum示例:strconv.Atoi(strings.TrimPrefix(filepath.Base(f), "part_"));若前缀复杂(如backup_20240501_part_042),先用strings.Split或正则提取数字再转int
合并前后必须校验 SHA256,不能只比文件大小
os.Stat().Size 一致 ≠ 内容正确。末尾丢几个字节、中间某块被截断、I/O 中断未写满——这些都导致大小不变但内容损坏,ZIP、PDF、视频直接不可用。
- 分割前:用
sha256.New()+io.Copy流式算原始哈希 - 合并后:对新文件做同样哈希计算,对比两个
[32]byte值是否相等 - 校验失败必须立刻删掉目标文件和所有分片——留着脏数据比报错更危险
真正耗时的从来不是合并动作本身,而是排序逻辑写错、校验跳过、或误用缓冲读取——这几个点漏一个,秒级就变成小时级排查。


















