将位写入C中的文件
我有这个字符串:“101”我想把它写成一个文件,在C中,而不是文本:“101”,所以8位x char。 但直接使用字符串作为位:位“1”,位“0”和位“1”,因此文件将为3位。
有可能吗? 我在网上搜索过,我试过这样做:
char c[25] = "101"; FILE *binFile = fopen("binFile.bin", "wb"); int x = atoi(c); fwrite(&x, sizeof(x), 1, binFile);
但最后,当我validation文件的字节时,Windows告诉我它是4bytes文件! 而不是3bits!
如果有可能,我怎么能这样做? 非常感谢。
所有文件系统¹都以字节为单位处理文件(并以更大的粒度分配存储空间,每次最少512字节)。 你无法获得3位长的文件。
你能做的最好就是用掉一整个字节,但忽略其中的5位。 要做到这一点(假设数字总是适合一个字节),将输入字符串转换为整数类型:
long l = strtol(c, 0, 2);
然后得到它最不重要的字节:
unsigned char b = l & 0xffl;
并将其写入文件:
fwrite(&b, 1, 1, binFile);
¹好吧,也许不是全部。 某些研究人员可能会在某个地方尝试使用比特大小的文件系统。 我不知道。
您的输出文件长度为4个字节,因为您正在为文件写入int
。 在大多数平台上, int
大小为4个字节。
您一次不能写少于1个字节。
您可以做的是将其写为位(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%,字符串越长,当然开销百分比越少。
关于你的方法的2注:
-
[现代]计算机在内存中处理不到1个字节,因此您无法将单个位写入磁盘。
此外,文件系统通常以文件适合的块(512字节,1Kb,…)分配空间。 因此,如果您有一个500字节的文件,实际上您将丢失512字节的磁盘空间。
-
atoi()
不会从字符串转换为二进制数,而是转换为整数。 你实际上写的是0b1100101
,即0d101
。 你应该先进行转换。 就像是:char b = 0; for (int i=0; c[i]!=NULL; i++) { b = ((b<<1) | atoi(c[i])); }
您没有写入位101
,而是写入十进制数101
的二进制值,即1100101
。 因为你的大小是sizeof(x)
字节,你的文件将是sizeof(x)
字节长。