【问题标题】:Writing bits to a file in C在 C 中将位写入文件
【发布时间】:2012-10-26 12:06:03
【问题描述】:

我有这个字符串:“101” 我想将它写入 C 中的文件,而不是文本:“101”等 8 位 x 字符。但是直接将字符串用作位:位“1”,位“0”和位“1”,这样文件将是3位。

有可能吗? 我在网上搜索并尝试这样做:

char c[25] = "101";
FILE *binFile = fopen("binFile.bin", "wb");
int x = atoi(c);
fwrite(&x, sizeof(x), 1, binFile);

但最后,当我验证文件的字节时,Windows 告诉我它是 4bytes 文件!而不是 3 位!

如果可能的话,我该怎么做?非常感谢。

【问题讨论】:

标签: c file binary


【解决方案1】:

所有文件系统¹都以字节为单位处理文件(并以更大的粒度分配存储空间,一次最少 512 个字节)。你不可能得到一个 3 位 长的文件。

你能做的最好的就是用完一个完整的字节,但忽略其中的 5 个位。为此(假设数字总是适合一个字节),请将输入字符串转换为整数类型:

long l = strtol(c, 0, 2);

然后得到它的最低有效字节:

unsigned char b = l & 0xffl;

并将其写入文件:

fwrite(&b, 1, 1, binFile);

¹好吧,也许不是全部。可能有一些研究人员在某处试验位大小的文件系统。我不知道。

【讨论】:

  • 我猜他会写很多单独的位,为了最终压缩,他可以创建一个缓冲版本的fwrite(),一旦它被填满,它就会一次刷新整个字节。
【解决方案2】:

您的输出文件长度为 4 个字节,因为您正在向该文件写入 int。在大多数平台上,int 的大小为 4 个字节。

您一次不能写入少于 1 个字节。

【讨论】:

    【解决方案3】:

    您可以将其写入位 (3) 并用 0 填充到一个字节。 但是,您还需要以实际使用的位数(或最后一个字节的位数)开始(或结束)。

    例如(使用第一个字节作为长度):

    00000011   -> 3, meaning from the last (and only byte in this case, 
                  only the first 3 bits are used)
    10100000   -> 101 is the string, other 5 bits are 0, just use for padding
    

    在这种情况下,第一个(长度)字节的开销为 50%,字符串越长,开销百分比当然越小。

    【讨论】:

      【解决方案4】:

      关于您的方法的 2 个注意事项:

      1. [现代] 计算机无法处理少于 1 个字节的内存,因此您无法将单个位写入磁盘。

        此外,文件系统通常以适合文件的块(512 字节,1Kb,...)分配空间。所以,如果你有一个 500 字节的文件,你实际上会失去 512 字节的磁盘空间。

      2. atoi() 不会从字符串转换为二进制数,而是转换为整数。你实际上是在写0b1100101,也就是0d101。您应该先进行转换。比如:

        char b = 0;
        for (int i=0; c[i]!=NULL; i++) 
        {
            b = ((b<<1) | atoi(c[i]));
        }
        

      【讨论】:

        【解决方案5】:

        你写的不是101,而是十进制数101的二进制值,即1100101。因为您是fread,大小为sizeof(x) 字节,所以您的文件将是sizeof(x) 字节长。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-07
          • 2021-06-07
          • 2015-02-19
          • 1970-01-01
          • 2010-12-23
          • 1970-01-01
          • 1970-01-01
          • 2015-12-22
          相关资源
          最近更新 更多