按位读取二进制文件

10

我知道下面的函数:

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

它只能逐字节读取,我的目标是能够每次读取12位,然后将它们存入数组中。非常感谢任何帮助或指点!


18
抱歉,一个字节是你能进行的最小粒度。你将不得不求助于(发抖)实际编程来拆分12位实体。 - Hot Licks
1
我认为你想要这个答案:https://dev59.com/Q3VC5IYBdhLWcg3w7V73 - Jessedc
6个回答

8

这是我要做的,我会告诉你它是如何工作的!非常感谢!!这可能是正确的方式!! - Ryan

3
很多年前,我为一个Huffman编码器编写了一些用于读写比特的C语言I/O例程。我创建了类似于read(2)和write(2)的函数,可以要求从流中读取13位比特。例如,对于编码,字节将被输入到编码器中,并且可变数量的比特将在另一侧出现。我有一个简单的结构体,其中包含一个指向当前正在读取或写入的字节中比特的指针。每次它超过末尾时,它将完成的字节刷新并将指针重置为零。不幸的是,那段代码早已消失,但从开源的Huffman编码器中分解出来看看如何解决这个问题可能是一个好主意。同样,base64编码将3个数据字节转换为4个(反之亦然)。

1
每个压缩库都有类似的东西。ffmpeg/libavutil中的这个看起来可以重复使用。 - Alan Curry

3
我已经实现了一些逐位读写文件的方法。 在这里 你可以找到它们。无论对于你的使用情况是否可行,你必须自己决定。我尽可能使代码最易读、最优化,但我目前不是经验丰富的C开发人员。
内部使用“bitCursor”存储先前未完全占用一个字节的比特信息。它有两个数据字段:d 存储数据,s 存储大小或光标中存储的位数。
你有四个函数:
  • newBitCursor(),它返回一个带有默认值{0,0} 的 bitCursor 对象。在从文件读取或写入序列之前,需要这样的光标。
  • fwriteb(void *ptr, size_t sizeb, size_t rSizeb, FILE *fp, bitCursor*c),它将 ptr 中存储的最右边的 sizeb 位写入 fp。
  • fcloseb(FILE *fp, bitCursor *c),如果之前的写入没有完全封装需要写入的所有数据,则写入剩余的一个字节,这很可能几乎总是这种情况...
  • freadb(void *ptr, size_t sizeb, size_t rSizeb, FILE *fp, bitCursor*c),它读取 sizeb 位并将它们按位 到 *ptr 中。(因此,你有责任将 *ptr 初始化为 0
注释中提供了更多信息。祝玩得开心!
编辑:今天我知道了,当我制作它时,我假设是小端! :P 哎呀!意识到自己仍然是个菜鸟总是很好的 ;D。
编辑:GNU 的二进制文件描述符

2
端序(x86是小端序)开始,从a_file文件指针中读取前两个字节,并检查最小或最大字节中的位,使用位移运算符。不能将位放入数组中,因为没有位数据类型。与其在数组中保留1和0,这样效率低下,不如将两个字节保存在双元素数组(例如,类型为unsigned char *)中,并编写函数将这两个字节映射到4096(2^12)个感兴趣的值之一。作为一个复杂性,在后续读取中,如果要通过指针每12位进行fread,则只需读取一个字节,使用上次读取剩余的位构建新的12位值。如果没有剩余,需要读取两个字节。您的映射函数需要处理使用了先前读取的位的第二种情况,因为两个字节需要不同的映射。为了高效地执行此操作,可以在读取计数器上使用模数来在两个映射之间交换。

1

读取2个字节并执行位运算将完成下一次读取第2个字节后应用位运算将返回您期望的结果...


0

针对您的问题,您可以查看此演示程序,它读取2个字节,但实际信息只有12位。此类事情通常使用位访问。

fwrite()是一个标准库函数,它将大小参数作为字节和int类型进行传递。因此,无法精确地读取12位。如果您创建的文件如下所示,则可以解决您的问题。

如果该文件是由其他人编写的特殊文件,则请遵循为该文件提供的标准以进行阅读,我认为他们也会像这样编写。或者您可以提供确切的位置,我可以帮助您。

#include<stdio.h>
#include<stdlib.h>
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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接