为什么“大小”和“磁盘大小”之间存在如此大的差异?

vfs*_*aki 307 filesystems

正如您在下面看到的,我的文件夹中的大小磁盘大小字段之间存在很大差异。这是为什么?

屏幕截图显示 1,504 个文件夹中的 50,875 个文件,105 MB 是磁盘上的 1.43 GB

我知道由于 Windows 中的分配单元,磁盘上的 Size应该比Size 大一点,但是为什么差别这么大呢?会不会是因为文件多?

顺便说一句,这个文件夹在我 Android 手机的 SD 卡上。在其中,我的地图应用程序存储其缓存的地图,该应用程序从 Google 地图获取其地图。

Bob*_*Bob 309

我将假设您在这里使用 FAT/FAT32 文件系统,因为您提到这是一张 SD 卡。NTFS 和 exFAT 在分配单元方面的行为相似。其他文件系统可能有所不同,但无论如何 Windows 都不支持它们。

如果你有很多小文件,这当然是可能的。考虑一下:

  • 50,000 个文件。

  • 32 kB 簇大小(分配单位),这是 FAT32 的最大值

好的,现在占用的最小空间是 50,000 * 32,000 = 1.6 GB(使用 SI 前缀,而不是二进制,以简化数学运算)。每个文件在磁盘上占用的空间始终是分配单元大小的倍数 - 在这里我们假设每个文件实际上都小到可以容纳在一个单元中,还有一些(浪费的)空间。

如果每个文件的平均大小为 2 kB,那么您总共会得到大约 100 MB - 但由于分配单元的大小,您平均也浪费了 15 倍(每个文件 30 kB)。


深入讲解

为什么会发生这种情况?好吧,FAT32 文件系统需要跟踪每个文件的存储位置。如果要保留每个字节的列表,则表(如地址簿)将以与数据相同的速度增长 - 并浪费大量空间。所以他们所做的是使用“分配单元”,也称为“集群大小”。卷被划分为这些分配单元,就文件系统而言,它们不能被细分——这些是它可以寻址的最小块。就像您有门牌号一样,但您的邮递员并不关心您有多少间卧室或住在其中的人。

那么如果你有一个非常小的文件会发生什么?好吧,文件系统并不关心文件是 0 kB、2 kB 还是 15 kB,它会给它尽可能小的空间——在上面的例子中,这是 32 kB。你的文件只使用了这个空间的一小部分,其余的基本上都被浪费了,但仍然属于文件——就像你离开无人居住的卧室一样。

为什么有不同的分配单元大小?嗯,这变成了拥有更大桌子(地址簿,例如说约翰在 123 Fake Street、124 Fake Street、666 撒旦巷等处拥有一所房子)或每个单元(房子)浪费更多空间之间的权衡。如果你有更大的文件,使用更大的分配单元更有意义——因为在所有其他单元都被填满之前,一个文件不会得到一个新的单元(房子)。如果你有很多小文件,那么无论如何你都会有一张大桌子(地址簿),所以不妨给他们小单位(房子)。

如果您有很多小文件,大分配单元通常会浪费大量空间。对于一般用途,通常没有充分的理由超过 4 kB。


碎片化?

至于碎片,碎片不应该以这种方式浪费空间。大文件可能会被分割,即分割成多个分配单元,但每个单元都应该在下一个开始之前填充。碎片整理可能会在分配表中节省一点空间,但这不是您的具体问题。


可能的解决方案

正如Gladiator2345 建议的那样,此时您唯一真正的选择是接受它或使用较小的分配单元重新格式化。

您的卡可能采用 FAT16 格式,它对表大小的限制较小,因此需要更大的分配单元才能处理更大的卷(上限为 2 GB,分配单元为 32 kB)。来源Braiam 提供。如果是这种情况,无论如何您都应该能够安全地格式化为 FAT32。

  • 由于最小分配大小而浪费的空间实际上在技术上称为“内部碎片”,因此您*可以*说碎片是罪魁祸首。但这仍然不是任何“碎片整理”工具都可以做的事情。 (4认同)
  • (从技术上讲,它只是被称为“松弛”。) (3认同)
  • 好吧,他可以将他的小文件存档压缩成一个大文件。 (2认同)

Bra*_*iam 45

这是压缩/归档到单个文件可能有帮助的情况之一。什么鲍勃在他的回答说是真实的,但解决方案可能比reformating盘其他答案建议更容易。如果您压缩或归档目录(使用 zip、tar 或任何其他方法),文件系统将看到您有一个大文件,而不是几个较小的文件。即使不压缩,您也将获得近 1.4 GiB 的空间,因为所有这些“小文件”都将被视为一个大文件。

在其中,我的地图应用程序存储其缓存的地图,该应用程序从 Google 地图获取其地图

也许您应该与开发人员讨论使用存档或数据库而不是多个文件。这可能也有助于减少磁盘碎片,并且肯定会节省空间,特别是如果它是 NAND 闪存驱动器。如果你解释 100MB 的有效载荷/有用数据变成 1.4GiB 的荒谬情况,那么数据的存储方式有问题,开发人员应该带来更好的解决方案。

  • @Braiam 这并不是让文件系统认为只有一个文件;**是**只有一个文件。至于为什么开发人员不将缓存信息存储在存档中,可能是因为大多数存档格式都不是为快速随机写入而设计的,而缓存肯定需要这种格式。更好的选择可能是使用像 SQLite 这样的轻量级数据库库。 (17认同)
  • 这是完全正确的。我想暂时,我应该改变我的应用程序。 (4认同)

min*_*ins 26

如前所述,大小差异的最常见原因是已用空间与已分配空间。但这不是唯一可能的,NTFS 具有向文件添加隐藏数据的功能。这种可能性是2019 年底医疗保健行业勒索软件所利用的可能性。

文件分叉和备用数据流

Resource fork ”自 1984 年以来一直被 Apple (Macintosh) 用于将程序的主要内容(指令)和相关资源(如图标和菜单)存储在同一文件中。在可执行文件中嵌入资源是一种常用技术,但使用 fork 则不然。

苹果一贯设计 Macintosh 文件系统来支持文件分叉,当微软设计 NTFS 来代替 FAT 时,分叉也以“替代数据流”(ADS)的名义被引入。

在 NTFS 中,文件包含:

  • 强制未命名数据流 (UDS)
  • 一个或多个可选的备用数据流 (ADS)。

隐藏在显眼的地方

文件分叉也不错,除了NTFS ADS不被包括Windows资源管理器在内的常见工具支持,ADS实际上是一个隐藏功能,是黑客的意外礼物。来自维基百科

备用流未在 Windows 资源管理器中列出,它们的大小不包括在文件大小中。

虽然仅报告 UDS 大小的文件大小不会因 ADS 的存在而改变,但分配的大小(文件系统分配给文件的集群)报告文件的实际大小,包括所有流。

Windows 资源管理器不报告 ADS,也不报告 CMD 命令dir。但是 ADS 是可见的:

请注意,仍然可以通过使用文件系统保留关键字对其中一些工具隐藏 ADS(请参阅下面链接的 Pierce 文档)。

  • Windows 使用 ADS 将文件标记为从 Internet 下载并存储其他元数据。

  • 黑客使用 ADS 来隐藏恶意活动的数据和代码。

值得一读的ADS综合说明:

恶意软件使用 ADS

严重的反恶意软件工具会监视 ADS,但恶意软件仍在大规模使用 ADS,因为:

  • 一些安全套件甚至不知道 ADS,或者无法识别 ADS 的恶意使用。
  • 将合法文件的执行重定向到 ADS 很容易(例如使用快捷方式)。

支付宝

勒索BitPaymer进入计算机作为一个正常的和可见的文件,但执行时作为ADS在一个合法的文件复制自身,然后删除初始文件。由于这不会改变合法文件的大小,并且 ADS 未被常见工具列出,因此恶意软件现在实际上是隐藏的。

钴猫行动

使用 ADS 隐藏

我的观点是:如果观察到大文件大小差异(超过集群大小:4KB),请不要忽视 ADS 和隐藏恶意软件的可能性。

自己试验 ADS

要安全地试验 ADS,请在 DOS/CMD 级别尝试此操作...

在 C 的根目录中创建并显示文件的内容:

C:\> echo The main data stream> test.txt
C:\> type test.txt
Run Code Online (Sandbox Code Playgroud)

结果:

C:\> The main data stream
Run Code Online (Sandbox Code Playgroud)

现在用同样的方法添加一个ADS,只需在文件名之外指定ADS名称:

C:\> echo The secret message> test.txt:secret
Run Code Online (Sandbox Code Playgroud)

您刚刚在文件中隐藏了秘密消息。请注意,尽管我们在 ADS“秘密”中添加了字节,但资源管理器中的文件大小并没有改变。

尝试显示ADS内容:

C:\> type test.txt:secret
Run Code Online (Sandbox Code Playgroud)

结果:

The filename, directory name, or volume label syntax is incorrect.
Run Code Online (Sandbox Code Playgroud)

CMDtype无法显示 ADS 的内容。我们将使用记事本代替:

notepad test.txt:secret
Run Code Online (Sandbox Code Playgroud)

在记事本中我们可以看到ADS的内容:

The secret message
Run Code Online (Sandbox Code Playgroud)

您还可以在无害文本文件的 ADS 中隐藏完整的可执行文件,并随时运行它。财富不会伤害黑客:-)

  • 值得使用来自 [Sysinternals](http://technet.microsoft.com/en-us/sysinternals/bb897440.aspx) 的 Streams 等工具来检查 ADS 使用情况。例如,在 Windows 系统上下载的文件可能在 ADS 中标有来源,尽管这是很小的,不应该占用空间。它通常不会显示在目录或资源管理器输出中。它可能会占用块并加剧您正在调查的磁盘使用问题。. (4认同)

aru*_*vma 20

问题可能是因为集群大小。

根据微软的说法:

如果您没有对卷上包含的任何文件或文件夹使用 NTFS 压缩,则 SIZE 和 SIZE ON DISK 之间的差异会浪费空间,因为簇大小大于必要的大小。您应该尝试使用最佳簇大小,以便 SIZE ON DISK 值尽可能接近 SIZE 值。SIZE ON DISK 和 SIZE 值之间的过大差异表明默认簇大小对于您存储在卷上的平均文件大小来说太大了,应该减小它。这只能通过备份卷然后使用 format 命令和 /a 开关重新格式化卷来指定适当的分配大小来完成:IE:(format D: /a:2048 此示例使用 2 KB 群集大小)。

尝试使用较小的簇大小格式化驱动器。

  • 话虽如此,不应使集群大小小于 4096 字节或只是不是这个数字的倍数。32 位操作系统使用的页面(在非 PAE 情况下)为 4096 字节,因此使用非多个集群可能会对文件系统性能产生负面影响。这就是默认大小设置为 4096 字节的原因。 (4认同)
  • 补充一下@Ruslan 所说的,较新的硬盘驱动器现在有 4 kB 的扇区大小,最好将文件系统与物理扇区对齐,并将物理扇区大小的倍数作为分配单元大小。 (2认同)

小智 9

我看到很多人建议使用较小的集群大小重新格式化驱动器。由于这是一张 SD 卡,请注意许多供应商将卡预先格式化为推荐的簇大小以匹配 NAND 簇大小的大小(保持两者同步对于最佳读/写性能和减少磨损非常重要)

您无法更改 NAND 的簇大小(它是 SD 卡硬件的物理属性)。

首先在您的 SD 卡上运行 scandisk/chkdsk 以确保大小报告问题不在损坏的文件系统中。

其次,我建议你向谷歌地图开发人员报告这个错误,因为他们是这里的罪魁祸首。他们应该使用高级存储方法。由于更少的 I/O 和文件系统的驱动程序活动,修复它也应该使应用程序在许多设备上运行得更快。


Cyb*_*ull 7

这是许多文件系统的普遍问题。这里有两个因素在起作用,文件系统可以处理每个逻辑卷的最大“块”数和存储介质的物理限制。任何给定的块只能分配 1 个文件(文件通常根据需要占用尽可能多的块)。因此,一个 64 字节的文本文件通常可以占用 4k 到 32k 的大小,具体取决于它所在文件系统的块大小。

一种思考方式是将文件系统中的每个块视为一个盒子,将文件系统视为一个房间。你所有的盒子都是一样的大小,你试着在一个房间里尽可能多地装上。如果你把它们都装进去,还有更多的空间,你必须得到更大的盒子,这样房间才能完全装满盒子。

把东西放在盒子里的规则之一是你不能把两个不相关的东西放在一个盒子里。它们必须是同一文档的一部分。所以如果我要输入一页文本,它会有它自己的框。如果我输入的文本页数太多,我无法将其全部放入一个框中,我只需找到另一个框并继续将页面放入其中,重复此操作直到我将所有页面都归档。我还会写下我用于该文档的框以及框的顺序以依次阅读它。

根据我组织箱子的方式,我的清单中可能只有足够的空间容纳一定数量的箱子。因此,如果我有一个很大的房间要装满,但只有少量的箱子,我将不得不使用非常大的箱子来达到房间的容量。

因此,在这种情况下,我的一页文档仍将占据一个盒子,没有其他内容共享它。

在各种存储解决方案中也会出现相同的情况。FAT32 只能管理当今巨大硬盘驱动器上被认为数量很少的“盒子”,因此它最终会使用非常大的“盒子”来弥补这一点。


kri*_*iss 6

您应该查看维基百科中的 Block Suballocation 条目。这正是发生在你身上的事情。除了更改分配集群大小之外,使用支持尾部打包的文件系统是解决此问题的文件系统级解决方案。

都有需要重新格式化磁盘的不便。

在某些情况下,仅将这些文件存储在存档中就可以解决问题(并且除了停止在文件末尾丢失空间之外,小文件也会被压缩)。这样做的不便之处是要花一些时间进行减压。

如果由于某些特定的应用程序相关问题而有这么多小文件,另一种选择是使用另一种方法(可能在数据库中)存储您的软件数据。但当然,它是为程序员而非最终用户提供的解决方案。

http://en.wikipedia.org/wiki/Tail_packing


Arc*_*ano 6

除了集群大小之外,您还可能因以下情况而产生差异:

  • 压缩或加密文件可以使用与逻辑文件大小不同的空间。
  • 链接文件会报告n倍链接数乘以文件大小为逻辑文件大小,但使用的物理空间通常较少。

  • 是的,我只是想通过提供更多可能的差异原因来补充答案。 (3认同)