在 C 中将位写入文件

问题描述 投票:0回答:6

我有这个字符串:“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 告诉我这是 4 字节文件!而且不是 3 位!

如果可能的话,我该如何做到这一点?非常感谢。

c file binary
6个回答
36
投票

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

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

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

然后获取其最低有效字节:

unsigned char b = l & 0xffl;

并将其写入文件:

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

¹ 嗯,也许不是全部。某些地方可能有一些研究人员正在尝试位大小的文件系统。我不知道。


15
投票

您的输出文件长度为 4 个字节,因为您正在向该文件写入

int
。在大多数平台上,
int
的大小为 4 个字节。

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


7
投票

你可以做的就是把它写成位(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%,字符串越长,开销百分比当然越少。


6
投票

关于您的方法的 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]));
    }
    

4
投票

您写的不是位

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


0
投票

使您存储的位值的管理既易于写入又易于检索的一种选择是使用数据库表来存储位值。这样,任何填充都会自动为您处理,并且您仍然可以获得一种有效的方式来存储位,而无需进行大量数学和按位运算。

MySQL 可以免费使用并支持位列类型,然后根据您对数据的处理方式,它可能也更容易使用,这里是 MySQL 中字段如何工作的简短说明 - https:/ /dev.mysql.com/doc/refman/8.0/en/bit-type.html

这里是他们页面的链接,显示如何在应用程序中运行嵌入式 MySQL 数据库,因此它内置于您的程序内部,用户无需安装任何类型的数据库即可使用该程序 - https:// /dev.mysql.com/doc/refman/5.7/en/libmysqld.html

如果您只是存储相对少量的状态标志或设置,那么数据库可能会有点过分,但如果它存储的内容类似于游戏中的玩家物品,而且可能变得非常复杂,那么数据库比将平面文件存储在数据库中要好得多。文件夹。我已经编写了一些东西,将数百个小文件存储到一个目录作为数据存储,我可以报告说,到目前为止,这从来都不是一个好主意。

© www.soinside.com 2019 - 2024. All rights reserved.