同样是 1GB,为什么复制照片文件夹比复制一部视频还慢?

· 更新日期: · · Windows, Windows 11, 文件复制, 性能, SSD, NAS, ZIP, robocopy

1GB 的视频一下就复制完了,可是合计 1GB 的照片文件夹却迟迟结束不了。换了新 SSD,一搬细碎的文件,传输速度又骤降。

容量一样,时间似乎也该一样,但决定复制时间的不只是“要搬多少字节”,还有“要处理多少个文件”。

本文是写给在 Windows 11 上把照片和资料复制到移动硬盘、NAS 的普通用户的入门介绍。先讲原理,再介绍在自己的环境里比较同样总容量数据的步骤。内容基于 2026 年 9 月 5 日确认的官方资料,不是对特定电脑或 NAS 的测速结果。

1.“搬 1GB”和“处理 1 万件”是两种不同的活

用搬家来想:即使行李总重量相同,一个大箱子和一万个要核对收件人的小包裹,费的工夫也不一样。文件也有在搬运内容之前和之后要做的事。

同样的容量,不同的文件数量同样是合计 1GB 的数据,一个文件和大量文件的管理处理次数并不相同。合计 1GB 的数据一个大文件一万个小文件按文件计的处理很少按文件计的处理不断重复

图 1: 字节数相同,文件数量未必相同。

Microsoft 也说明过:跨网络依次复制大量小文件时,数据传输之外的处理会起作用,导致跑不满线路速度。1

当然,这不是“照片慢、视频快”这种按格式划分的规律。几张大照片和几万个小图片,条件本来就不同。先在文件夹属性里同时看看总大小和文件数量。比较时要对齐的不是“占用空间”,而是文件内容的合计字节数。

图中实线表示始终成立的关系,虚线表示带条件的关系(成立条件写在详情页各关系的说明中)。关系的完整列表(共 11 条,附依据与确信度)以及主要概念的定义,汇总在知识地图详情页(日文)。数据:JSON-LD / Turtle

2. 复制时处理的不只是内容

复制文件时,要打开源文件、创建目标文件、读写内容,再设置必要的信息并关闭。Windows 打开文件的处理还要处理访问权限、能否与其他处理同时打开等条件。2

名称、大小、日期等用于管理文件的信息称为元数据。例如 NTFS 这种文件系统,会把每个文件的管理信息记录在 MFT(主文件表)等结构中。它不是“把照片的像素数据写完就结束”的机制。3

复制一个文件时要做的事除了读取源文件,还要为每个文件创建目标、管理信息并关闭。打开源文件创建目标文件读写内容整理信息并关闭下一个文件同样重复

图 2: 这是概念性的流程。实际的处理顺序和并行执行,会因复制方式和文件系统而异。

用 SSD 也不会让这份管理工作消失。仅凭产品标称的大传输速度数字,算不出复制一万个文件要多久。另外,把小文件的复制直接叫成“全是随机 I/O”也过于粗糙。除了读写的位置分布,还要把处理文件本身的开销分开来考虑。

3. 对 NAS 来说,还要加上“等对方回话的时间”

NAS 是通过网络使用的存储设备。Windows 共享文件夹使用的 SMB(Server Message Block)中,有些场景要把文件操作委托给对端,然后等待对端处理并回应。

跨网络的文件操作电脑发出的操作请求经过网络成为对端的文件处理,回应再返回电脑。电脑发出文件操作请求经过网络对端处理文件回应返回电脑

图 3: 一次能运多少,和一个操作多快得到回复,是两回事。

相当于道路车道数的是带宽,相当于回复所需时间的是延迟。每个小文件都要等一下,那么即使带宽有富余,传输量也上不去。杀毒软件的检查也可能影响每个文件的处理时间。1

不过,这并不意味着每个文件一定要通信固定的次数。SMB 有把请求合并的机制,缓存和并行处理的条件也会改变等待的方式。45 家庭局域网和远端的共享文件夹,结果也会不同。

为了用数字思考而做的简化例子

假设处理没有重叠、依次进行,思路就是下面这样。

复制时间 ≒ 合计字节数 ÷ 数据传输速度
         + 文件数量 × 每个文件的附加时间

这既不是实测值,也不是 Windows 的精确计算公式。 为了说明,假设数据部分是 100MB/秒,附加时间是每个文件 2 毫秒。这里 1GB=1,000MB。

1GB 的数据部分是 10 秒。文件只有 1 个时附加是 0.002 秒,而一万个则是 20 秒,合计约 30 秒。这是省略了并行化、缓存、CPU 与存储限制的模型,但足以说明“容量相同、时间却不同”。

把复制时间拆成两部分来看区分由合计容量决定的传输时间,和随文件数量累积起来的附加时间。与合计容量相应的时间整体的复制时间与文件数量相应的附加时间

图 4: 文件数量一多,只看数据量时看不见的时间就开始起作用。

4. ZIP 不只是“变小”,还有“合并成一个”

ZIP 既有压缩数据的作用,也有把多个文件装进一个容器的作用。JPEG 本来就是压缩过的格式,做成 ZIP 后容量可能减不了多少。6

即便如此,传输时要处理的文件从一万个变成一个,这个效果是另外一回事。只看压缩率就断定“做成 ZIP 没意义”,为时过早。

ZIP 的两种作用打包成 ZIP 带来的文件数量变化,和压缩带来的容量变化是不同的效果。把照片打包成 ZIP要传输的文件只有一个容量的变化取决于内容

图 5: 就算几乎压不动,要传输的文件个数还是能减少。

不过,打包的处理和解压的处理都不是免费的。如果希望照片仍然以普通文件夹的形式使用,就要用下面这个合计来比较。

经由 ZIP 的耗时 = 制作 ZIP + 传输 ZIP + 解压

制作 ZIP 时要读取小文件,解压时又要在目标位置重新创建。关键不是消除按文件计的工作,而是改变这些工作发生的位置和传输的形态。 如果传输前后的处理很重,不打包反而可能更快。1

5.“在哪里解压”会改变 ZIP 的效果

如果把 ZIP 发到接收端的电脑,并在那台电脑的本地驱动器上解压,就不必把小文件一个一个送上网络。Microsoft 的指引也提到把归档文件在传输目标的系统上解压的做法。1

在传输目标解压与从电脑解压到共享位置区分在传输目标内部解压的路径,和电脑把解压出的文件写到共享位置的路径。把 ZIP 送到传输目标由传输目标自己在内部解压用电脑上的应用解压把小文件送到共享位置

图 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 完全一致。

三种比较用数据制作合计容量相同的大文件与小文件群,再由后者制作无压缩 ZIP。准备同样合计 1GB1GB 的文件一个100KB 的文件一万个把同样内容做成无压缩 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 如果中途报错停下,就不要把这一次纳入测量,并检查提示中显示的实验用文件夹。清理时也要先确认那是自己创建的文件夹再动手。

统一测量的条件

统一源端与目标端的设备、网络和复制方式。一开始三种数据都用文件资源管理器复制,不使用移动。目标端每次都用新的空文件夹,避免混入跳过已有文件或覆盖确认的情况。

统一比较条件的步骤固定复制路径与方式,向空的目标位置调换顺序多次复制,完成后还要核对内容。同样的设备·路径·方式每次都用空的目标位置调换顺序测多次核对件数与内容

图 8: 不要把“已复制的文件被跳过”省下的时间,当成传输变快的结果。

每种情况例如各测 3 次,调换顺序,记录中位数和波动。Windows 会把文件缓存在内存中,所以有时只有第二次变快。就算换了新的目标文件夹,读取端的缓存也不会消失。这套步骤得到的是接近日常复制的趋势,而不是严格无缓存下的介质性能。5

同一物理驱动器内的复制会让读写互相竞争,不要和复制到另一台设备的情况混在一起。仅在线的云端文件会带入获取时间,请不要使用;杀毒软件、同步等条件也不要中途更改。

情形 制作时间 传输时间 解压时间 到照片等可用为止的合计
A:一个大文件 属于比较用的准备,因此排除 实测并记录 不需要 传输时间(作为对照)
B:一万个小文件 属于比较用的准备,因此排除 实测并记录 不需要 传输时间
C:把 B 打包的无压缩 ZIP 记录 ZIP 的制作 实测并记录 需要时记录 制作+传输+解压

这是用来记录的表格,里面没有填入结果数值。A 是用来观察传输性质的对照,因为文件结构不同,它并不能代替 B。B 与 C 的实用比较,目标是把同一组文件放到同一个最终保存位置。解压的位置也务必记录下来。

复制或解压之后,要核对件数与合计字节数,必要时用哈希确认内容。核对时的读取要放在计时之外,并记下它也会影响下一次尝试的缓存。复制窗口关闭为止的时间,并不等于“可以承受断电的状态”所需的时间,因此也不要做“刚复制完就拔掉外接设备”的实验。5

7. 无法做成 ZIP 时,就一点一点地并行复制

如果希望在目标端立刻使用单个文件,或者每次只发送有变化的文件,那么打包成 ZIP 就未必合适。Windows 自带的 robocopy 提供了并行处理多个文件的 /MT89

把按文件计的等待时间并行起来同时推进多个文件的处理,就能在一个文件等待期间推进另一个文件的传输。并行处理多个文件文件 A 在等待响应文件 B 正在传输把等待时间叠起来

图 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

厘清复制变慢的原因把只有小文件才慢的情况,和与数据种类无关都慢的情况分开来查。只有小文件慢?看文件数量与等待时间也检查设备、连接与负载同时确认有无失败或断开

图 10: 小文件跑不上速度,和复制失败或设备异常,不是同一回事。

如果出现复制失败、连接中断,或者比以前突然变差,就不要只用文件数量来解释了事。优先保全重要数据,并确认日志和设备的状态。

另外,不建议为了提速而停用杀毒软件或禁用 SMB 签名。SMB 签名的作用之一是防止通信被篡改。10 在受管理的电脑上不要绕过设置,请与负责人沟通。

总结

复制时间里既有与数据量相应的时间,也有与文件数量相应的工作。这就是“同样是 1GB,时间未必相同”的原因。

要试 ZIP,就不要只看压缩率,而要把制作、传输、解压都算上。要试并行复制,一次就只改并行数。在换更快的设备之前,把总大小和文件数量放在一起看,会更容易想明白现在的 Windows 上到底发生了什么。

参考链接

  1. Microsoft Learn, Slow SMB files transfer speed. 关于大量小文件、文件创建与通信及检查的负担、并行复制以及在传输目标解压归档文件。  2 3 4 5

  2. Microsoft Learn, CreateFileW function. 关于打开与创建文件的操作、访问权限与共享模式。 

  3. Microsoft Learn, Master File Table. 关于 NTFS 保存每个文件管理信息的机制。 

  4. Microsoft Open Specifications, Sending Compounded Requests. 关于 SMB2 把多个相关操作合并发送的机制。 

  5. Microsoft Learn, File Caching. 关于系统文件缓存,以及延迟写入再落盘的机制。  2 3 4

  6. Microsoft Support, Zip and unzip files. 关于用 ZIP 聚合文件,以及 JPEG 再压缩也难以变小。 

  7. Microsoft Learn, Compress-Archive. 关于 NoCompression 的指定与隐藏文件等限制。  2

  8. Microsoft Learn, robocopy. 关于并行数、重试、日志、复制选项与退出代码。  2

  9. Microsoft Learn, Performance Tuning for SMB File Servers. 关于针对小文件复制的 robocopy 并行化与日志输出。 

  10. Microsoft Learn, SMB signing overview. 关于 SMB 签名的保护目的与运维上的思路。 

共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。

与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。

本文与以下服务页面相关联,欢迎从最接近的入口查看。

常见问题

汇总了咨询这一主题时常见的问题。

容量一样,为什么复制照片文件夹更慢?
复制不只是把内容搬过去。创建文件、管理文件信息、关闭文件等处理,每个文件都会发生一次。小文件一多,这些处理和等待时间所占的比重就会上升。比起“照片”这种格式本身,文件的数量和单个文件的大小更重要。
用 SSD 或高速局域网,小文件的复制也会变慢吗?
会。即使用 SSD,文件管理的处理依然存在;复制到 NAS 等设备时,还要加上等待通信和对端处理的时间。连续传输大文件时的速度,和处理大量小文件的速度是两回事。
JPEG 打包成 ZIP 也变不小,那还有意义吗?
即使容量几乎没减少,把要传输的文件合并成一个仍然有效果。不过创建和解压 ZIP 也要花时间。在需要解压的场景下,要用创建、传输、解压的合计时间来比较。
把 ZIP 传到 NAS,再用电脑解压到共享文件夹,会更快吗?
那种做法是把解压出来的小文件从电脑写到 NAS,于是跨网络的文件创建又发生了一遍。这与由 NAS 自身的功能在内部解压是两回事,请把解压也算进去一起测量。
robocopy 的并行复制是不是开得越多越快?
不是。并行化可以把文件处理的等待时间叠起来,但同时也会增加存储和 NAS 的负担。请从较小的并行数开始在相同条件下比较,并用日志确认复制是否失败或遗漏。

作者简介

本文作者的个人简介页面。

Go Komura

小村软件有限公司 代表

以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。

返回博客列表