同样是 1GB,为什么复制照片文件夹比复制一部视频还慢?
· 更新日期: · Go Komura · Windows, Windows 11, 文件复制, 性能, SSD, NAS, ZIP, robocopy
1GB 的视频一下就复制完了,可是合计 1GB 的照片文件夹却迟迟结束不了。换了新 SSD,一搬细碎的文件,传输速度又骤降。
容量一样,时间似乎也该一样,但决定复制时间的不只是“要搬多少字节”,还有“要处理多少个文件”。
本文是写给在 Windows 11 上把照片和资料复制到移动硬盘、NAS 的普通用户的入门介绍。先讲原理,再介绍在自己的环境里比较同样总容量数据的步骤。内容基于 2026 年 9 月 5 日确认的官方资料,不是对特定电脑或 NAS 的测速结果。
1.“搬 1GB”和“处理 1 万件”是两种不同的活
用搬家来想:即使行李总重量相同,一个大箱子和一万个要核对收件人的小包裹,费的工夫也不一样。文件也有在搬运内容之前和之后要做的事。
flowchart TB
accTitle: 同样的容量,不同的文件数量
accDescr: 同样是合计 1GB 的数据,一个文件和大量文件的管理处理次数并不相同。
A["合计 1GB 的数据"] --> B["一个大文件"]
A --> C["一万个小文件"]
B --> D["按文件计的处理很少"]
C --> E["按文件计的处理不断重复"]
图 1: 字节数相同,文件数量未必相同。
Microsoft 也说明过:跨网络依次复制大量小文件时,数据传输之外的处理会起作用,导致跑不满线路速度。1
当然,这不是“照片慢、视频快”这种按格式划分的规律。几张大照片和几万个小图片,条件本来就不同。先在文件夹属性里同时看看总大小和文件数量。比较时要对齐的不是“占用空间”,而是文件内容的合计字节数。
图中实线表示始终成立的关系,虚线表示带条件的关系(成立条件写在详情页各关系的说明中)。关系的完整列表(共 11 条,附依据与确信度)以及主要概念的定义,汇总在知识地图详情页(日文)。数据:JSON-LD / Turtle
2. 复制时处理的不只是内容
复制文件时,要打开源文件、创建目标文件、读写内容,再设置必要的信息并关闭。Windows 打开文件的处理还要处理访问权限、能否与其他处理同时打开等条件。2
名称、大小、日期等用于管理文件的信息称为元数据。例如 NTFS 这种文件系统,会把每个文件的管理信息记录在 MFT(主文件表)等结构中。它不是“把照片的像素数据写完就结束”的机制。3
flowchart TB
accTitle: 复制一个文件时要做的事
accDescr: 除了读取源文件,还要为每个文件创建目标、管理信息并关闭。
A["打开源文件"] --> B["创建目标文件"]
B --> C["读写内容"]
C --> D["整理信息并关闭"]
D -.-> E["下一个文件同样重复"]
图 2: 这是概念性的流程。实际的处理顺序和并行执行,会因复制方式和文件系统而异。
用 SSD 也不会让这份管理工作消失。仅凭产品标称的大传输速度数字,算不出复制一万个文件要多久。另外,把小文件的复制直接叫成“全是随机 I/O”也过于粗糙。除了读写的位置分布,还要把处理文件本身的开销分开来考虑。
3. 对 NAS 来说,还要加上“等对方回话的时间”
NAS 是通过网络使用的存储设备。Windows 共享文件夹使用的 SMB(Server Message Block)中,有些场景要把文件操作委托给对端,然后等待对端处理并回应。
flowchart TB
accTitle: 跨网络的文件操作
accDescr: 电脑发出的操作请求经过网络成为对端的文件处理,回应再返回电脑。
A["电脑发出文件操作请求"] --> B["经过网络"]
B --> C["对端处理文件"]
C --> D["回应返回电脑"]
图 3: 一次能运多少,和一个操作多快得到回复,是两回事。
相当于道路车道数的是带宽,相当于回复所需时间的是延迟。每个小文件都要等一下,那么即使带宽有富余,传输量也上不去。杀毒软件的检查也可能影响每个文件的处理时间。1
不过,这并不意味着每个文件一定要通信固定的次数。SMB 有把请求合并的机制,缓存和并行处理的条件也会改变等待的方式。45 家庭局域网和远端的共享文件夹,结果也会不同。
为了用数字思考而做的简化例子
假设处理没有重叠、依次进行,思路就是下面这样。
复制时间 ≒ 合计字节数 ÷ 数据传输速度
+ 文件数量 × 每个文件的附加时间
这既不是实测值,也不是 Windows 的精确计算公式。 为了说明,假设数据部分是 100MB/秒,附加时间是每个文件 2 毫秒。这里 1GB=1,000MB。
1GB 的数据部分是 10 秒。文件只有 1 个时附加是 0.002 秒,而一万个则是 20 秒,合计约 30 秒。这是省略了并行化、缓存、CPU 与存储限制的模型,但足以说明“容量相同、时间却不同”。
flowchart TB
accTitle: 把复制时间拆成两部分来看
accDescr: 区分由合计容量决定的传输时间,和随文件数量累积起来的附加时间。
A["与合计容量相应的时间"] --> C["整体的复制时间"]
B["与文件数量相应的附加时间"] --> C
图 4: 文件数量一多,只看数据量时看不见的时间就开始起作用。
4. ZIP 不只是“变小”,还有“合并成一个”
ZIP 既有压缩数据的作用,也有把多个文件装进一个容器的作用。JPEG 本来就是压缩过的格式,做成 ZIP 后容量可能减不了多少。6
即便如此,传输时要处理的文件从一万个变成一个,这个效果是另外一回事。只看压缩率就断定“做成 ZIP 没意义”,为时过早。
flowchart TB
accTitle: ZIP 的两种作用
accDescr: 打包成 ZIP 带来的文件数量变化,和压缩带来的容量变化是不同的效果。
A["把照片打包成 ZIP"] --> B["要传输的文件只有一个"]
A --> C["容量的变化取决于内容"]
图 5: 就算几乎压不动,要传输的文件个数还是能减少。
不过,打包的处理和解压的处理都不是免费的。如果希望照片仍然以普通文件夹的形式使用,就要用下面这个合计来比较。
经由 ZIP 的耗时 = 制作 ZIP + 传输 ZIP + 解压
制作 ZIP 时要读取小文件,解压时又要在目标位置重新创建。关键不是消除按文件计的工作,而是改变这些工作发生的位置和传输的形态。 如果传输前后的处理很重,不打包反而可能更快。1
5.“在哪里解压”会改变 ZIP 的效果
如果把 ZIP 发到接收端的电脑,并在那台电脑的本地驱动器上解压,就不必把小文件一个一个送上网络。Microsoft 的指引也提到把归档文件在传输目标的系统上解压的做法。1
flowchart TB
accTitle: 在传输目标解压与从电脑解压到共享位置
accDescr: 区分在传输目标内部解压的路径,和电脑把解压出的文件写到共享位置的路径。
A["把 ZIP 送到传输目标"] --> B["由传输目标自己在内部解压"]
C["用电脑上的应用解压"] --> D["把小文件送到共享位置"]
图 6: 只知道“ZIP 在 NAS 上”,并不代表解压处理也在 NAS 内部进行。
这里很容易搞错。用电脑的文件资源管理器打开 NAS 上的 ZIP,把解压目标指定为同一个共享文件夹,那么电脑解压出的小文件还是要写到 NAS,细碎的网络操作又会重新发生。
请把它与“NAS 自身带有对应的解压功能、可以从管理界面等在 NAS 内部执行”的情况区分开。如果没有这类功能,就不要认为“送个 ZIP 就解决了”,而要测量实际使用的整条路径。要比较“解压到 NAS 内部”和“解压到电脑本地”时,也别忘了文件最终放置的位置并不相同。
6. 用同样的 1GB,比较大文件、小文件与 ZIP
一开始拿手头的视频和照片来试也没关系。不过它们的内容、文件数量、可压缩程度都不一样,想厘清原因时就要用实验数据。以下不是速度测量结果,而是读者在自己环境中执行的比较步骤。
要准备的是三样:一个大文件、一万个小文件,以及把这一万个打包成的无压缩 ZIP。A 和 B 的内容合计都精确为 1,000,000,000 字节。C 还要加上 ZIP 的管理信息,所以文件大小不会与 A、B 完全一致。
flowchart TB
accTitle: 三种比较用数据
accDescr: 制作合计容量相同的大文件与小文件群,再由后者制作无压缩 ZIP。
A["准备同样合计 1GB"] --> B["1GB 的文件一个"]
A --> C["100KB 的文件一万个"]
C --> D["把同样内容做成无压缩 ZIP"]
图 7: 用无压缩 ZIP,更容易把压缩率的差异和合并文件数量的效果分开观察。
制作实验用文件(可选)
这一节写给会用命令的读者。在 Windows PowerShell 5.1 及以上,于本地的临时文件夹中新建一个实验用文件夹。仅大文件与小文件群就约占 2GB,加上 ZIP 约 3GB,传输目标也另需空闲容量。为了不把磁盘塞满,源盘请至少留出 5GB 左右的余量。
这里不使用你已有的照片和资料。生成的是伪随机数据,因此不是能当作视频或照片打开的文件。它避免了只用全零数据时那种极端的压缩效果,但也无法重现针对真实照片的检查和应用行为。
$ErrorActionPreference = 'Stop'
$lab = Join-Path ([System.IO.Path]::GetTempPath()) ('copylab-' + [guid]::NewGuid().ToString('N'))
$drive = New-Object System.IO.DriveInfo ([System.IO.Path]::GetPathRoot($lab))
if ($drive.AvailableFreeSpace -lt 5GB) {
throw '请在实验用驱动器上确保 5GB 以上的空闲容量。'
}
$largeDir = Join-Path $lab 'large'
$smallDir = Join-Path $lab 'small'
[System.IO.Directory]::CreateDirectory($largeDir) | Out-Null
[System.IO.Directory]::CreateDirectory($smallDir) | Out-Null
Write-Host "创建位置: $lab"
$fileCount = 10000
$buffer = New-Object byte[] 100000
$random = New-Object System.Random 20260905
$large = [System.IO.File]::Open(
(Join-Path $largeDir 'one.bin'),
[System.IO.FileMode]::CreateNew,
[System.IO.FileAccess]::Write,
[System.IO.FileShare]::None
)
try {
for ($i = 0; $i -lt $fileCount; $i++) {
$random.NextBytes($buffer)
$name = 'part-{0:D5}.bin' -f $i
[System.IO.File]::WriteAllBytes((Join-Path $smallDir $name), $buffer)
$large.Write($buffer, 0, $buffer.Length)
}
}
finally {
$large.Dispose()
}
Write-Host "准备完成。各数据组的内容为 $([long]$fileCount * $buffer.Length) 字节。"
同一段字节序列会同时写入小文件和一个大文件。接着在同一个 PowerShell 窗口里制作无压缩 ZIP,并在这里记录制作时间。NoCompression 表示不压缩、直接存入 ZIP。7
$zip = Join-Path $lab 'small.zip'
$watch = [System.Diagnostics.Stopwatch]::StartNew()
Compress-Archive -LiteralPath $smallDir -DestinationPath $zip -CompressionLevel NoCompression
$watch.Stop()
Write-Host "制作 ZIP: $($watch.Elapsed.TotalSeconds) 秒"
Write-Host "ZIP 的大小: $((Get-Item -LiteralPath $zip).Length) 字节"
这套步骤只适用于刚生成的普通文件。Compress-Archive 有忽略隐藏文件等限制,请不要直接拿它给重要文件夹做完整备份。7 如果中途报错停下,就不要把这一次纳入测量,并检查提示中显示的实验用文件夹。清理时也要先确认那是自己创建的文件夹再动手。
统一测量的条件
统一源端与目标端的设备、网络和复制方式。一开始三种数据都用文件资源管理器复制,不使用移动。目标端每次都用新的空文件夹,避免混入跳过已有文件或覆盖确认的情况。
flowchart TB
accTitle: 统一比较条件的步骤
accDescr: 固定复制路径与方式,向空的目标位置调换顺序多次复制,完成后还要核对内容。
A["同样的设备·路径·方式"] --> B["每次都用空的目标位置"]
B --> C["调换顺序测多次"]
C --> D["核对件数与内容"]
图 8: 不要把“已复制的文件被跳过”省下的时间,当成传输变快的结果。
每种情况例如各测 3 次,调换顺序,记录中位数和波动。Windows 会把文件缓存在内存中,所以有时只有第二次变快。就算换了新的目标文件夹,读取端的缓存也不会消失。这套步骤得到的是接近日常复制的趋势,而不是严格无缓存下的介质性能。5
同一物理驱动器内的复制会让读写互相竞争,不要和复制到另一台设备的情况混在一起。仅在线的云端文件会带入获取时间,请不要使用;杀毒软件、同步等条件也不要中途更改。
| 情形 | 制作时间 | 传输时间 | 解压时间 | 到照片等可用为止的合计 |
|---|---|---|---|---|
| A:一个大文件 | 属于比较用的准备,因此排除 | 实测并记录 | 不需要 | 传输时间(作为对照) |
| B:一万个小文件 | 属于比较用的准备,因此排除 | 实测并记录 | 不需要 | 传输时间 |
| C:把 B 打包的无压缩 ZIP | 记录 ZIP 的制作 | 实测并记录 | 需要时记录 | 制作+传输+解压 |
这是用来记录的表格,里面没有填入结果数值。A 是用来观察传输性质的对照,因为文件结构不同,它并不能代替 B。B 与 C 的实用比较,目标是把同一组文件放到同一个最终保存位置。解压的位置也务必记录下来。
复制或解压之后,要核对件数与合计字节数,必要时用哈希确认内容。核对时的读取要放在计时之外,并记下它也会影响下一次尝试的缓存。复制窗口关闭为止的时间,并不等于“可以承受断电的状态”所需的时间,因此也不要做“刚复制完就拔掉外接设备”的实验。5
7. 无法做成 ZIP 时,就一点一点地并行复制
如果希望在目标端立刻使用单个文件,或者每次只发送有变化的文件,那么打包成 ZIP 就未必合适。Windows 自带的 robocopy 提供了并行处理多个文件的 /MT。89
flowchart TB
accTitle: 把按文件计的等待时间并行起来
accDescr: 同时推进多个文件的处理,就能在一个文件等待期间推进另一个文件的传输。
A["并行处理多个文件"] --> B["文件 A 在等待响应"]
A --> C["文件 B 正在传输"]
B --> D["把等待时间叠起来"]
C --> D
图 9: 并行化是把等待时间叠起来的方法,并不会让线路或磁盘本身变快。
下面是从刚才创建的 $smallDir 复制的例子。只需把 $targetRoot 改成自己有写入权限的目标位置。每次都创建不同的目标文件夹,并且不使用会删除源数据或目标数据的选项。
$targetRoot = '\\NAS\share\CopyLab' # 改成自己的目标位置
$runId = [guid]::NewGuid().ToString('N')
$target = Join-Path $targetRoot ('small-mt8-' + $runId)
$log = Join-Path $lab ('robocopy-' + $runId + '.log')
robocopy $smallDir $target /E /MT:8 /R:1 /W:1 /XJ "/LOG:$log"
$code = $LASTEXITCODE
if ($code -ge 8) {
throw "复制中出现了失败。退出代码=$code、日志=$log"
}
Write-Host "退出代码=$code。请确认日志中的复制件数、失败件数以及目标位置的内容: $log"
/MT:8 是 8 个线程,/R:1 /W:1 是失败时的重试次数与等待秒数,/LOG 是保存日志。robocopy 即使退出代码为 1 也属于正常复制,8 及以上则含有失败。0~7 并不意味着可以省去内容确认。8
/MT:8 只是比较的起点示例,不是最优值。并行数开得过多会加重对端负担,反而可能更慢。1 请用同样的方法比较 /MT:1 与 /MT:8,把一次改动的条件限制到最少。不要根据同时改动了 ZIP 与并行化的结果,去判断其中某一项的效果。
8. 在断定“慢就是坏了”之前
是只有大量小文件慢,还是大文件也慢?把同样的文件复制到本地又如何?把这些分开,就能缩小要排查的范围。如果是复制到一半速度下降,那也可能是缓存的影响,光看显示的速度无法确定原因。5
flowchart TB
accTitle: 厘清复制变慢的原因
accDescr: 把只有小文件才慢的情况,和与数据种类无关都慢的情况分开来查。
A{"只有小文件慢?"} -->|是| B["看文件数量与等待时间"]
A -->|否| C["也检查设备、连接与负载"]
B --> D["同时确认有无失败或断开"]
C --> D
图 10: 小文件跑不上速度,和复制失败或设备异常,不是同一回事。
如果出现复制失败、连接中断,或者比以前突然变差,就不要只用文件数量来解释了事。优先保全重要数据,并确认日志和设备的状态。
另外,不建议为了提速而停用杀毒软件或禁用 SMB 签名。SMB 签名的作用之一是防止通信被篡改。10 在受管理的电脑上不要绕过设置,请与负责人沟通。
总结
复制时间里既有与数据量相应的时间,也有与文件数量相应的工作。这就是“同样是 1GB,时间未必相同”的原因。
要试 ZIP,就不要只看压缩率,而要把制作、传输、解压都算上。要试并行复制,一次就只改并行数。在换更快的设备之前,把总大小和文件数量放在一起看,会更容易想明白现在的 Windows 上到底发生了什么。
参考链接
-
Microsoft Learn, Slow SMB files transfer speed. 关于大量小文件、文件创建与通信及检查的负担、并行复制以及在传输目标解压归档文件。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, CreateFileW function. 关于打开与创建文件的操作、访问权限与共享模式。 ↩
-
Microsoft Learn, Master File Table. 关于 NTFS 保存每个文件管理信息的机制。 ↩
-
Microsoft Open Specifications, Sending Compounded Requests. 关于 SMB2 把多个相关操作合并发送的机制。 ↩
-
Microsoft Learn, File Caching. 关于系统文件缓存,以及延迟写入再落盘的机制。 ↩ ↩2 ↩3 ↩4
-
Microsoft Support, Zip and unzip files. 关于用 ZIP 聚合文件,以及 JPEG 再压缩也难以变小。 ↩
-
Microsoft Learn, Compress-Archive. 关于 NoCompression 的指定与隐藏文件等限制。 ↩ ↩2
-
Microsoft Learn, Performance Tuning for SMB File Servers. 关于针对小文件复制的 robocopy 并行化与日志输出。 ↩
-
Microsoft Learn, SMB signing overview. 关于 SMB 签名的保护目的与运维上的思路。 ↩
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
Windows 的“硬件加速 GPU 计划”是什么?打开就会变快吗?
面向普通用户图解 Windows 的硬件加速 GPU 计划(HAGS):它改变了什么、开与关如何判断、设置项不显示的原因、与帧生成的关系,以及安全的对比步骤。
为什么“剩余1秒”迟迟不结束?── 进度条与剩余时间的工作原理
剩余1秒持续很久、卡在99%、一直显示准备中,分别是怎么回事?从进度的分母、速度预测、最后的处理步骤和界面更新逐一解释,并提供同一任务不同进度显示的交互演示。
磁盘使用率 100% 要停掉什么才能好?──分辨 SysMain、Windows Search 与 Defender
从处理量、响应时间和文件三个角度厘清 Windows 磁盘使用率 100% 的原因。图解 SysMain 的临时停止与恢复、Windows Search 搜索范围的调整,以及不停用 Defender 的调查方法。
关掉内存完整性(HVCI)会变快吗 ── 含义、步骤与判断
Windows 安全中心「内核隔离」里的内存完整性(HVCI)到底在做什么,关掉它真的会变快吗。本文面向入门读者,梳理可能变快的条件与不会变的条件、关闭的步骤与恢复方法、如何确认真的关掉了,以及什么情况下可以关。
Windows 应用的深色模式与对比度主题支持 ── DWM 的深色标题栏、WinForms/WPF 跟随系统主题、高对比度下的绘制
讲解如何让 WinForms/WPF 应用跟随 Windows 11 的深色模式与对比度主题。梳理 DWM 的深色标题栏、.NET 9/10 的 SetColorMode 与 ThemeMode、主题切换的检测,以及高对比度下用系统颜色绘制的做法。
相关主题
与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。
Windows 技术主题
汇整 KomuraSoft LLC 关于 Windows 开发、故障调查与既有资产活用文章的主题中心。
常见问题
汇总了咨询这一主题时常见的问题。
- 容量一样,为什么复制照片文件夹更慢?
- 复制不只是把内容搬过去。创建文件、管理文件信息、关闭文件等处理,每个文件都会发生一次。小文件一多,这些处理和等待时间所占的比重就会上升。比起“照片”这种格式本身,文件的数量和单个文件的大小更重要。
- 用 SSD 或高速局域网,小文件的复制也会变慢吗?
- 会。即使用 SSD,文件管理的处理依然存在;复制到 NAS 等设备时,还要加上等待通信和对端处理的时间。连续传输大文件时的速度,和处理大量小文件的速度是两回事。
- JPEG 打包成 ZIP 也变不小,那还有意义吗?
- 即使容量几乎没减少,把要传输的文件合并成一个仍然有效果。不过创建和解压 ZIP 也要花时间。在需要解压的场景下,要用创建、传输、解压的合计时间来比较。
- 把 ZIP 传到 NAS,再用电脑解压到共享文件夹,会更快吗?
- 那种做法是把解压出来的小文件从电脑写到 NAS,于是跨网络的文件创建又发生了一遍。这与由 NAS 自身的功能在内部解压是两回事,请把解压也算进去一起测量。
- robocopy 的并行复制是不是开得越多越快?
- 不是。并行化可以把文件处理的等待时间叠起来,但同时也会增加存储和 NAS 的负担。请从较小的并行数开始在相同条件下比较,并用日志确认复制是否失败或遗漏。