逐位读取二进制文件

我知道下面的function:

size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file); 

它只能逐字节读取,我的目标是能够一次读取12位然后将它们放入一个数组中。 任何帮助或指针将不胜感激!

添加到第一个注释,您可以尝试一次读取一个字节(声明一个char变量并在那里写入),然后使用按位运算符>>和<<逐位读取。 点击此处了解更多信息: http : //www.cprogramming.com/tutorial/bitwise_operators.html

a_file文件指针读取前两个字节并检查最小或最大字节中的位 – 取决于平台的字节顺序 (x86是little-endian) – 使用bitshift运算符。

你不能真正将位放入数组,因为没有位的数据类型。 而不是将1和0保持在数组中,这是低效的,将两个字节保持在两个元素的数组(例如,类型为unsigned char * )和写入函数以将这两个字节映射到4096之一似乎更便宜(2 ^ 12)感兴趣的价值。

作为一个复杂因素,在后续读取中,如果要每12位读取指针,则只读取一个字节,使用前一次读取的剩余位来构建新的12位值。 如果没有剩余部分,则需要读取两个字节。

您的映射函数需要解决第二种情况,即从先前的读取使用位,因为这两个字节需要不同的映射。 为了有效地做到这一点,可以使用读计数器上的模数在两个映射之间交换。

我已经实现了几种方法来逐位读/写文件。 他们在这里 。 无论您的用例是否可行,您都必须自己决定。 我试图制作最易读,最优化的代码,而不是经验丰富的C开发人员(目前)。

在内部,它使用“bitCursor”来存储有关尚未适合整个字节的先前位的信息。 它具有以下数据字段: d存储数据和存储大小,或存储在游标中的位数。

你有四个function:

  • newBitCursor (),返回带有默认值的bitCursor对象
    {0,0}。 在对文件进行读取/写入操作的序列的开始处需要这样的游标。
  • fwriteb (void * ptr,size_t sizeb,size_t rSizeb,FILE * fp,bitCursor * c),它将存储在ptr中的值的最右边位写入fp。
  • fcloseb (FILE * fp,bitCursor * c),写入剩余的字节,如果先前的写入没有完全封装所有需要写入的数据,那可能几乎总是如此……
  • freadb (void * ptr,size_t sizeb,size_t rSizeb,FILE * fp,bitCursor * c),它读取sizeb位,按位OR将它们读取为* ptr。 (因此,你有责任将* ptr设为0

评论中提供了更多信息。 玩得开心!

编辑:今天我已经知道 ,当我做了我假设Little Endian! :P哎呀! 我总是很高兴知道我还有多少菜鸟; D。

编辑: GNU的二进制文件描述符 。

很多年前,我在C中为霍夫曼编码器编写了一些I / O例程。 这需要能够读取和写入比特的粒度而不是字节。 我创建了类似于read(2)和write(2)的函数,可以要求(例如)从流中读取13位。 例如,为了编码,字节将被馈送到编码器中,并且可变数量的比特将出现在另一侧。 我有一个简单的结构,其中一个位指针指向正在读取或写入的当前字节。 每次它结束时,它都会将完成的字节刷新并将指针重置为零。 不幸的是,代码早已不复存在,但是将开源Huffman编码器分开并看看问题是如何解决的可能是一个想法。 类似地,base64编码需要3个字节的数据并将它们变为4(反之亦然)。

读取2个字节并执行逐位操作将在下次读取后完成第二个字节以后应用逐位操作将返回您的预期。 。 。 。

对于你的问题你可以看到这个演示程序读取2byte但实际信息只有12位。除了这种类型的东西使用它有点访问。

fwrite()是一个标准的库函数 ,它将size参数作为byte和int类型。所以你不可能完全读取12bit。如果你创建的文件然后创建如下所示以及如下所示它解决你的问题。

如果该文件是不是由您编写的特殊文件,那么请遵循为该文件提供的标准来阅读我认为他们也只是这样写。或者您可以提供我可以帮助您的地方。

 #include #include struct node { int data:12; }NODE; int main() { FILE *fp; fp=fopen("t","w"); NODE.data=1024; printf("%d\n",NODE.data); fwrite(&NODE,sizeof(NODE),1,fp); NODE.data=0; NODE.data=2048; printf("%d\n",(unsigned)NODE.data); fwrite(&NODE,sizeof(NODE),1,fp); fclose(fp); fp=fopen("t","r"); fread(&NODE,sizeof(NODE),1,fp); printf("%d\n",NODE.data); fread(&NODE,sizeof(NODE),1,fp); printf("%d\n",NODE.data); fclose(fp); }