【问题标题】:How many bytes will be required to store number in binary and text files respectively分别在二进制文件和文本文件中存储数字需要多少字节
【发布时间】:2017-02-24 18:14:35
【问题描述】:

如果我想在一个文件中存储一个数字,比如 56789,那么将它分别存储在二进制文件和文本文件中需要多少字节?我想知道字节是如何分配给二进制和文本文件中的数据的。

【问题讨论】:

    标签: file c++11 binary file-handling


    【解决方案1】:

    这取决于:

    • 文本编码和数字系统(十进制、十六进制等等...)
    • 签名/未签名
    • 单个整数或多个(需要分隔符)
    • 数据类型
    • 目标架构
    • 使用压缩编码

    在 ASCII 中,一个字符占用 1 个字节。在 UTF-8 中,一个字符占用 1 到 4 个字节,但数字始终占用 1 个字节。在 UTF-16 或 Unicode 中,每个字符占用 2 个或更多字节。

    非 ASCII 格式的文件可能需要额外的 2 个字节 (initial BOM),这取决于创建文件时使用的编辑器和/或设置。

    但我们假设您将数据存储在一个简单的 ASCII 文件中,否则讨论会变得不必要地复杂。

    我们还假设您使用十进制数系统。

    在十六进制中,您使用数字 0-9 和字母 a-f 来表示数字。像34234324423 这样的十进制(base-10)将是十六进制(base-16)的7F88655C7。在第一个系统中,我们有 11 个数字,在第二个系统中只有 9 个数字。最小基数是 2(数字 01),常见的最大基数是 64(base-64)。从技术上讲,使用 ASCII 可以达到 base-96 甚至可能是 base-100,但这种情况非常少见。

    每个数字 (0-9) 占用一个字节。如果您有带符号的整数,则附加的减号将引导数字(因此负数会增加 1 个字节)。

    在某些情况下,您可能想要存储多个数字。您将需要一个分隔符来区分数字。逗号 (,)、冒号 (:)、分号 (;)、管道 (|) 或换行符 (LFCR 或 Windows CRLF,占用 2 个字节)都在 djungle 中作为数字的合法分隔符被观察到。

    什么是数字?在你的头脑中8这个数量的概念或想法就是数字。在石头、纸、磁带或屏幕上的像素上对该概念的任何表示都只是:表示。它们是代表您在大脑中理解的符号。那些是数字。请不要将数字与数字混淆,这种区别是数学和计算机科学的基础。

    在这些情况下,您希望为分隔符每个数字计算一个附加字符。或者可能每个数字减一。这取决于您是要终止每个数字用标记还是分隔数字:

    示例(三位数字和三个换行符):6 个字节

    1<LF>
    2<LF>
    3<LF>
    

    示例(三位数字和两个逗号):5 个字节

    1,2,3
    

    示例(四位数字和一个逗号):5 个字节

    2134,
    

    示例(符号和一位数字):2 个字节

    -3
    

    如果您以 二进制格式 存储数据(不要与 二进制数字系统 混淆,后者仍然是文本格式)占用的内存取决于整数类型(或者,更好的是整数的位长)。

    一个八位字节 (0..255) 将占用 1 个字节。不需要分隔符或前导符号。

    16 位 float 将占用 2 个字节。对于 C 和 C++,必须考虑底层架构。 32 位架构上的常见integer 将占用 4 个字节。针对 64 位架构编译的相同代码将占用 8 个字节。

    这些 flat 规则有一些例外。例如,Google 的 protobuf 使用 zig-zag VarInt 实现,该实现利用了可变长度编码

    Here is a VarInt implementation in C/C++.


    编辑:添加了 Thomas Weller 的建议

    除了实际的文件CONTENT之外,您还必须存储有关文件的元数据(用于记账,例如第一个扇区、文件名、访问权限等)。占用磁盘空间的文件没有显示此元数据,但实际上存在。

    如果您将每个数字存储在单独的文件中,例如将数字 10 存储在文件 result-10 中,则这些元数据条目将占用比数字本身更多的空间。

    如果您在一个文件中存储十个、一百个、数千个或数百万/十亿个数字,则该开销变得越来越无关紧要。

    More about metadata here.


    编辑:更清楚文件开销

    如上所述,开销与环境相关。

    但这不是文本格式和二进制格式之间的区别。正如doug65536所说,无论您存储数据如何,如果文件系统结构相同,那没关系。

    一个文件就是一个文件,如果它包含二进制数据或ASCII文本。

    不过,上述推理的适用与您选择的格式无关。

    【讨论】:

    • @ThomasWeller 哈哈!这是个好建议!没有考虑维护文件系统本身的开销。谢谢!
    • 为什么文件系统是相关的?无论如何,您都可以存储一些东西。
    • @doug65536 这是因为从问题中不清楚他是使用 1 个文件来存储 MB 数据还是许多(数千个)文件。这是低效的,我不会那样做,但我们真的不知道他做了什么。此外,根据操作系统的不同,大文件的开销扩展也不同(在 Linux inode 上随文件大小线性扩展,在 NTFS 上不一样,我们不知道他使用什么)。我还在回答中说,如果他将数据 “存储在一个文件中,那么开销变得越来越无关紧要”。文本/二进制格式之间的大小不同,因此上述推理。否则——文件就是文件。
    • @doug65536 我已经编辑了我的答案(最后一部分),因此很明显我并不是说他选择的格式有任何区别。这是一个完全独立的事情,不受他的问题的约束,但总体上仍然是相关的知识。
    【解决方案2】:

    在给定的基数中存储一个数字所需的位数是ceil(log(n)/log(base))

    以十进制存储为以 10 为底,以十六进制文本存储以 16 为底。以二进制存储为以 2 为底。

    以二进制形式存储时,通常需要向上取整为 8 的倍数或 2 的幂,但可以以打包格式存储具有异常位数的值。

    给定您的示例数字(暂时忽略负数):

    56789 in base 2 needs 15.793323887 bits (16)
    56789 in base 10 needs 4.754264221 decimal digits (5)
    56789 in base 16 needs 3.948330972 hex digits (4)
    56789 in base 64 needs 2.632220648 characters (3)
    

    表示符号需要一个额外的字符或位。

    要查看二进制与文本的比较,假设一个字节是 8 位,每个 ASCII 字符将是文本编码中的一个字节(8 位)。一个字节的范围是 0 到 255,十进制数字的范围是 0 到 9。每个字符(8 位)每个字节可以编码大约 3.32 位数字(log(10)/log(2))。二进制编码每个字节可以存储 8 位数字。将数字编码为文本需要大约 2.4 倍的空间。如果您填充数字以使它们在字段中对齐,那么数字的存储编码非常差,典型的宽度为 10 位,您将存储 80 位,这将是 33 位二进制编码数据。

    【讨论】:

      【解决方案3】:

      我在这方面还不是很发达;但是,我相信这不仅是内容的情况,还包括附带的 META-DATA。但是,如果您只是在谈论数字,则可以将其存储为 ASCII 或二进制形式。

      在二进制中,56789 可以转换为1101110111010101;有一种“简单”的方法可以在纸上解决这个问题。但是,http://www.binaryhexconverter.com/decimal-to-binary-converter 是一个可以用来转换它的网站。

      1101110111010101 有 16 个字符,因此 16 位即两个字节。

      【讨论】:

      • 我很确定他不想将其保存为文本格式的二进制数字。他可以将其存储为文本(string text = "56789";,至少占用 5 个字节)或数字(int number=56789;,占用 4 个字节,假设为 Int32)。
      • @ThomasWeller 等等,他说 16 位是两个字节。
      • @doug65536:这是偶然的,取 OP 编号 (56789) 并假设 intInt16,大多数编程语言并非如此。答案并不准确,因为它没有告诉您在 9、10、11、12、13、14 或 15 位二进制数上您仍然需要 2 个字节。
      • @ThomasWeller 是的,我认为真正的答案涉及ceil(log(n)/log(base)),其中基数为 10 或 2,每个字符放大到 8 位,并且位四舍五入到下一个 8 的倍数。加一用于标志等
      【解决方案4】:

      每个整数通常大约有 4 个字节的存储空间。因此,如果您将数字以二进制形式存储在文本文件中,并且二进制等效值为 1101110111010101,则该二进制数中有 16 个整数。 16 * 4 = 64。所以你的数字将占用大约 64 字节的存储空间。如果您的整数以 64 位而不是 32 位存储,则每个整数将占用 8 个字节的存储空间,因此您的总数将等于 128 个字节。

      【讨论】:

        【解决方案5】:

        在发布任何问题之前,您应该进行研究。

        文件的大小取决于许多因素,但为简单起见,如果您使用 UTF-8 编码,则在文本格式中,每个字符的数字将占用 1 个字节。另一方面,长数据类型的二进制值将占用 4 个字节。

        【讨论】:

          猜你喜欢
          • 2020-10-10
          • 1970-01-01
          • 2018-12-11
          • 2018-11-21
          • 2011-08-27
          • 2013-04-19
          • 1970-01-01
          • 1970-01-01
          • 2012-01-07
          相关资源
          最近更新 更多