【问题标题】:What's the smallest possible file size on disk?磁盘上可能的最小文件大小是多少?
【发布时间】:2021-07-22 20:38:30
【问题描述】:

我正在尝试找到一种解决方案,将二进制文件存储在磁盘上的最小尺寸中。我正在从 30 字节的数据库中读取车辆 VIN 和车牌号,当我将其放入 txt 文件并保存时,它的大小为 30B,但它在磁盘上的大小为 4KB,这意味着如果我保存 100000 个文件或更多,它会占用存储空间。

所以我的问题是,如何将这 30B 写入单个二进制文件,使其在磁盘上的最小大小,以及磁盘上 30B 的最小可能大小是多少,包括文件名和权限等其他信息?

注意:我不想将这些文本保存在数据库中,我只想制作单独的二进制文件。

【问题讨论】:

  • 最大的问题是 - 我们在谈论什么文件系统?有了答案,阅读上述文件系统,你就会得到答案。
  • 这真的取决于你使用的文件系统。
  • 正如其他 cmets 所说,这非常依赖于文件系统。现在 400MB 什么都不是,何必担心呢?
  • "我不想将这些文本保存在数据库中,我只想制作单独的二进制文件。" 你别无选择。 “二进制文件”是数据库中的一个条目。文件系统是数据库。选择一个满足您需求的数据库还是一个不满足您需求的数据库只是一个问题。
  • @Ross,这是效率问题。将 400MB 的数据保存在 30B 的数据包中,每个数据包占用 4K,这将占用超过 50TB 的硬盘空间!

标签: c++


【解决方案1】:

文件的最小大小始终是磁盘的集群大小,通常为 4k。对于这样的数据,在一个文件中包含许多记录确实是唯一合理的解决方案。

虽然另一种可能性是将这些文件存储在存档中,例如 zip 文件。在 windows 下,你甚至可以访问与资源管理器中的普通文件非常相似的 zip 内容。

另一种创造性的可能性:将所有数据仅存储在文件名中。一个零字节文件在 MFT 中只占用 1024 个字节。 (假设 NTFS)

编辑:阅读常驻文件,我发现在较新的 4k 扇区驱动器上,MFT 条目实际上也是 4k。所以无论数据大小是否为0,它都不会小于这个。

另一个编辑:包含数万或数十万条目的巨大目录将变得非常笨重。不要试图在资源管理器中打开一个,或者准备在加载时喝杯咖啡。

【讨论】:

  • 严格来说这不是真的。例如,NTFS 支持“常驻”文件,其中 DATA 流可以存储在文件的 MFT 记录中,因此最大约 1000 字节的文件不会比空文件占用更多的簇。
  • @AndrewMedico 大声笑,AKA 'NTFS 文件描述符是如此之大,以至于在存储它们的集群末尾留下了大量空间,因此我们添加了一个“驻留文件”功能来使用它用于小文件的数据。 (是的,这是一个猜测:)。
  • @AndrewMedico 提出了为什么 1 字节文件仍报告为 4k 的问题。
  • 可能是因为资源管理器实际上并不知道文件系统是否能够存储驻留数据(MFT 条目可能已经被一个很长的名称或其他流填充) - 所以它让事情变得简单,只是说每个文件至少占用一个集群。
  • 感谢大家快速安静地回答。正如我的问题所暗示的那样,我在这个领域相当新,我想知道是否可以使用 C++ 以编程方式更改集群大小,但根据您的回复,看起来这是不可能的。但是,我尝试了那种“创造性的可能性”!它看起来可能满足我的要求,这是一个慷慨的回应,再次感谢@ths。但是,虽然我会以编程方式测试 100000 个具有 30 个字符文件名的空文件的大小,但它会在文件夹大小为零的文件夹中查找其中的几个,这怎么可能?
【解决方案2】:

大多数文件系统将磁盘空间以块的形式分配给文件。除了可能为零长度的文件外,不能少于一个块。

谷歌“集群大小”

【讨论】:

    【解决方案3】:

    您应该考虑使用一些索引文件库,例如gdbm:它与任意键关联一些任意数据。您不会为每个关联花费一个文件(所有关联只需一个文件)。

    您应该重新考虑您对“数据库”的反对意见。 Sqlite 是一个,为您提供 SQL 和数据库功能。还有noSQLmongodb等数据库

    当然,所有这些都与操作系统和文件系统有关(但gdbmsqlite 应该适用于许多系统)。

    AFAIU,您可以同时配置和使用gdbmsqlite,以便能够非常高效地存储数百万个几十字节的条目。

    【讨论】:

      【解决方案4】:

      在文件系统上你有同样的问题。最小的分配大小是一个数据节点和一个 i 节点。例如,在 IBM JFS2 中,最小的块大小为 4k,您需要分配一个 inode。第二个问题是你会在短时间内写很多文件。在短时间内写入许多 inode 会造成性能问题。

      每个写操作都必须记录并提交。或者你我们是一个旧的非 jornaled 文件系统。

      一个想法是,grep 你的许多数据记录器在它们之间放置一个分隔符,并在一个文件中写入 200-1000。

      例如:

      0102030400506070809101112131415;;0102030400506070809101112131415;;...
      

      你可以用文件名索引 dem。序号左右....

      【讨论】:

        猜你喜欢
        • 2012-08-01
        • 2013-02-17
        • 2011-01-26
        • 1970-01-01
        • 2020-10-17
        • 2011-04-14
        • 1970-01-01
        • 1970-01-01
        • 2021-04-27
        相关资源
        最近更新 更多