为什么“大小”和“磁盘大小”之间有这么大的差异?

为什么“大小”和“磁盘大小”之间有这么大的差异?

正如你在下面看到的,尺寸磁盘大小文件夹中的字段。这是为什么?

屏幕截图显示 1,504 个文件夹中有 50,875 个文件,105 MB 占用磁盘空间 1.43 GB

我知道磁盘大小应该比尺寸因为 Windows 中的分配单元,但为什么差别这么大?可能是因为文件数量太多吗?

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

答案1

由于您提到这是 SD 卡,因此我假设您使用的是 FAT/FAT32 文件系统。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。您的文件只使用了其中的一小部分空间,其余空间基本上被浪费了,但仍属于文件 - 就像您空置的卧室一样。

为什么有不同的分配单元大小?嗯,这变成了一个权衡:是拥有更大的表(地址簿,例如说 John 在 123 Fake Street、124 Fake Street、666 Satan Lane 等地拥有一所房子),还是在每个单元(房子)中浪费更多空间。如果您有更大的文件,使用更大的分配单元更有意义 - 因为文件在所有其他单元都填满之前不会获得新的单元(房子)。如果您有很多小文件,那么您无论如何都会有一个大表(地址簿),所以不妨给它们小单元(房子)。

一般来说,如果您有大量小文件,那么较大的分配单元会浪费大量空间。通常没有理由将分配单元大小超过 4 kB 以供一般使用。


碎片化?

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


可能的解决方案

作为gladiator2345 建议,此时您唯一真正的选择是忍受它或使用更小的分配单元重新格式化。

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

答案2

这是一种将文件压缩/归档到单个文件可能会有所帮助的情况。鲍勃在他的回答中说是真的但解决方案可能比重新格式化磁盘更简单,正如其他答案所建议的那样。如果您压缩或存档目录(使用 zip、tar 或任何其他方法),文件系统将看到您有一个大文件,而不是几个较小的文件。即使不压缩,您也将获得近 1.4 GiB 的空间,因为所有这些“小文件”都将算作一个大文件。

在这里面,我的地图应用存储了它的缓存地图,并且该应用从谷歌地图获取地图

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

答案3

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

文件分叉和备用数据流

资源分叉“自 1984 年 (Macintosh) 以来,Apple 就一直使用这种方法将程序的主要内容 (指令) 和相关资源 (如图标和菜单) 存储在同一个文件中。将资源嵌入可执行文件是一种常见的技术,但使用 fork 来实现这一点却并不常见。

Apple 始终如一地设计 Macintosh 文件系统以支持文件分叉,而当 Microsoft 设计 NTFS 来取代 FAT 时,也引入了文件分叉,其名称为“备用数据流“(广告)。

在 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

结果:

C:\> The main data stream

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

C:\> echo The secret message> test.txt:secret

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

尝试显示ADS内容:

C:\> type test.txt:secret

结果:

The filename, directory name, or volume label syntax is incorrect.

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

notepad test.txt:secret

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

The secret message

您还可以将完整的可执行文件隐藏在无辜文本文件的 ADS 中,并随时运行它。财富对黑客来说没有危害 :-)

答案4

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

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

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

其次,我建议您向 Google Map 开发人员报告此错误,因为他们才是罪魁祸首。他们应该使用更高级的存储方法。修复此问题还应该使应用程序在许多设备上的运行速度更快,因为 I/O 和文件系统的驱动程序活动更少。

相关内容