文件传输协议

浏览器大文件传输的“零拷贝”边界:少复制比真零拷贝更现实

沿着 File.slice、ArrayBuffer、Worker、哈希、DataChannel 与接收存储分析内存复制,设计流式读取、可转移对象和有界缓冲。

把它做成生产功能之前,需要先拆开协议事实、产品承诺和运行成本,三者混在一起很容易得到错误结论。 网页无法像内核 sendfile 那样把文件描述符直接交给网络栈。所谓零拷贝通常是减少 JavaScript 堆上的重复副本:按窗口切片、把 ArrayBuffer 转移给 Worker、处理后及时释放引用,并避免把整文件拼成一个 Blob。

文件传输要同时对账发送偏移、接收落盘、分块校验和双方终态。进度条到达百分之百,只能说明字节进入队列,不能证明文件完整可用。

落地方案的关键部件

先把下面几项写成可评审的规则,而不是散落在回调和界面判断里。规则越清楚,后续扩容、兼容和排错越少靠猜。

  • 读取窗口与发送窗口共用字节预算,未确认数据不能无限提前读取。
  • Worker 之间用 transferable ArrayBuffer 转移所有权,转移后原线程不再访问。
  • 接收端分块持久化并流式计算摘要,完成前不创建第二份整文件内存副本。

浏览器里更诚实的目标是有界、少复制的流水线。只要内存峰值由窗口控制、取消能释放、摘要和存储可流式处理,就能稳定传超大文件。

别让错误假设进入生产

边界条件会把隐藏假设变成真实事故。弱网、刷新、并发和容量上限必须组合测试,因为单独出现时它们往往都能被重试掩盖。

  • 同一块为哈希、加密和发送分别 slice,峰值内存变成窗口的数倍。
  • Worker 转移后仍复用 detached buffer,偶发发送零长度或抛异常。
  • 取消任务只停网络循环,读取队列和 Worker 仍持有大量缓冲。

发布闸门应该检查什么

测试不能以“最后成功了”结束。还要测量经历了多少次副作用、等待多久、是否泄露内容,以及失败后再次执行能否从干净基线开始。

  1. 传输数倍于设备内存的虚拟文件,确认峰值随窗口而非文件大小增长。
  2. 在每个流水线阶段取消并强制 GC,检查缓冲引用、Worker 和存储事务全部释放。
  3. 对比 transferable 与复制消息的 CPU、内存和吞吐,选择真实收益而不是口号。

可以上线的标准是:用户知道当前发生了什么,系统在异常后能停止或恢复,资源不会无界增长,运维也能从最小必要证据定位阶段。

把方法变成一次真实连接

打开 uCopy,让两台设备在浏览器里安全连接并开始传输。

开始免费使用