编程进阶网 编程进阶网
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机组成原理
  • 操作系统原理
  • 网络协议原理
  • 数据库系统原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机组成原理
  • 操作系统原理
  • 网络协议原理
  • 数据库系统原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • ScriptHub 脚本工具箱
  • Python

  • Shell-Bash

  • 工具脚本

    • 工具脚本速查
    • 哈希校验
    • Base64编码
    • AES加解密
    • RSA签名验签
    • JWT令牌
    • JSON与YAML
    • XML与CSV
    • 编码转义
    • 图片转换
    • 文档转换
    • 批量重命名
    • 分割合并
      • 底层原理:流式 I/O vs 内存加载
      • 一、按行数分割
      • 二、按大小分割(分片上传场景)
      • 三、文件合并(流式优化版)
      • 四、Shell 命令
    • 目录同步
    • 文件监控
    • 压缩归档
    • 文件去重
    • cURL速查
    • HTTP调试
    • 端口DNS
    • 抓包代理
  • 自动化脚本

  • ScriptHub
  • 工具脚本
杨充
2025-08-21
目录

分割合并

# 分割合并

按行数/按大小分割文件、分片合并、大日志切割、分片上传。

# 底层原理:流式 I/O vs 内存加载

分割大文件(如 10GB 日志)时,绝不能使用 f.read() 一次性读入内存——那会 OOM。正确做法是流式处理:每次从磁盘读一小块(chunk),处理后立即写入输出文件,内存占用恒定为 chunk 大小。

f.read(size) 的参数 size 决定了内核缓冲区的大小:太大会浪费内存,太小会增加系统调用次数。经验值:8KB~64KB 是最优平衡点(与文件系统的 block size 对齐)。shutil.copyfileobj 默认 bufsize 为 16KB(16×1024=16384 字节)——恰好是 ext4/XFS 等文件系统的默认块大小倍数。

二进制 vs 文本模式:按大小分割文件时必须用 'rb'/'wb' 打开——二进制模式逐字节拷贝,不会引入换行符转换(\n ↔ \r\n)。文本模式分割二进制文件会损坏数据。

# 一、按行数分割

文本文件按行分割——适合日志分片。核心逻辑:逐行读取,每 N 行切换到新输出文件。enumerate(f, 1) 从 1 开始计数行号。

#!/usr/bin/env python3
from pathlib import Path

def split_by_lines(filepath, lines_per_file):
    """将文件分割为每 N 行的多个小文件——流式逐行,内存友好"""
    base, ext = Path(filepath).stem, Path(filepath).suffix
    with open(filepath) as f:
        part = 1
        out = open(f"{base}_part{part:03d}{ext}", 'w')
        for i, line in enumerate(f, 1):
            out.write(line)
            if i % lines_per_file == 0:
                out.close()
                part += 1
                out = open(f"{base}_part{part:03d}{ext}", 'w')
        out.close()
    print(f"✅ 分割为 {part} 个文件")

# 二、按大小分割(分片上传场景)

云存储(S3/OSS/COS)通常要求单个分片 5MB~5GB,推荐 10~100MB。此实现完全按字节切割,不关心文件类型——对 JPEG/PDF/视频同样有效。

#!/usr/bin/env python3
import os

def split_by_size(filepath, chunk_size_mb=10):
    """按字节大小拆分为多个文件片——纯二进制,无损"""
    chunk_size = chunk_size_mb * 1024 * 1024
    base = os.path.basename(filepath)
    with open(filepath, 'rb') as f:
        part = 0
        while True:
            chunk = f.read(chunk_size)
            if not chunk:               # read 返回空字节 → EOF
                break
            part += 1
            part_name = f"{base}.part{part:03d}"
            with open(part_name, 'wb') as out:
                out.write(chunk)
            print(f"  {part_name} ({len(chunk)/1024:.0f}KB)")
    print(f"✅ 分割为 {part} 片")

def merge_parts(output_path, *part_files):
    """合并分片——严格按传入顺序拼接,不做任何变换"""
    with open(output_path, 'wb') as out:
        for pf in part_files:
            with open(pf, 'rb') as f:
                out.write(f.read())
    print(f"✅ 合并完成 → {output_path}")

# 三、文件合并(流式优化版)

shutil.copyfileobj(fsrc, fdst) 内部使用 16KB 缓冲区循环读-写,避免了将整个源文件读入内存。对比 f.read() + out.write(),它在处理大文件时更稳定。

#!/usr/bin/env python3
import shutil, glob

def merge_files(output_path, input_pattern):
    """合并匹配模式的所有文件——sorted 保证顺序一致"""
    files = sorted(glob.glob(input_pattern))
    with open(output_path, 'wb') as out:
        for fpath in files:
            with open(fpath, 'rb') as fsrc:
                shutil.copyfileobj(fsrc, out)
            print(f"  + {fpath}")
    print(f"✅ 合并 {len(files)} 个文件 → {output_path}")

# 四、Shell 命令

split 的默认前缀是 x(生成 xaa, xab, ...),后缀两位字母。-d 切换为数字后缀,-a 控制后缀长度。

#!/bin/bash

# ===== split 命令 =====
split -l 1000 large.log part_               # 按行:每 1000 行一个文件
split -b 10M large.zip chunk_               # 按大小:每 10MB
split -d -a 3 -b 10M video.mp4 vid_         # -d 数字后缀 -a3 三位数

# ===== cat 合并——用 glob 顺序自然排序 =====
cat part_* > merged.txt                     # 字母序:part_aa, part_ab, ...
cat chunk_* > restored.zip
#工具#文件
上次更新: 2026/06/28, 17:55:19
批量重命名
目录同步

← 批量重命名 目录同步→

最近更新
01
科学方法实践论法
06-28
02
辩证思维矛盾论法
06-28
03
毛选中的调查观念
06-28
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 鄂ICP备2024073355号-1 | 鄂ICP备2024073355号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式