C fread如何读取二进制文件中的不同数据块?

时间:2017-10-02 07:01:35

标签: c porting fread

我将一些C代码移植到C#,但我对C知之甚少,但我很灵活,我可以学习新的编程语言。无论如何,我无法从我移植的代码中找出确切的行为。

我已经在网上了解了fread()

  fread(&(targetObj->data), sizeof(TestObj), 1, file);

现在,file是一个包含大量数据的大型二进制文件。

我想知道的是我如何在C#中做到这一点。 让我解释一下:

我认为这行代码可以做到这一点:

  • TestObj是一个无符号的短
  • 读取 1次一大块TestObj(unsigned short)数据
  • 将其从文件(指向文件系统上的二进制文件的指针)读取到targetObj-> data

我不明白的是:

我有一个很大的二进制文件,它实际上是什么读取的?有一些标题可以定义写入无符号短大小数据块的位置吗?

从二进制那个对象到底需要什么?我如何知道如何从C#中的二进制文件读回?也许C知道在哪里选择那个单一的无符号短片,但我不在C#

例如,如果该二进制文件中保存了40个无符号短路,则上面的C代码行只读取第一个?

如果我这样做

fread(&(targetObj->data), sizeof(TestObj), 5, file);

预计testObj->数据是5个无符号短路的数组? 代码将读取它在整个二进制文件中找到的前5个无符号短路?

我无法解决这个问题,但我需要知道C如何识别大二进制文件中的unsigned short,我不知道其中的内容,也无法思考如何我可以说在C#中读取该文件的第一个C unsigned short

3 个答案:

答案 0 :(得分:2)

fread只是从当前文件光标位置读取指定的字节数,并使文件光标前进(或“文件指针”,但不要与C指针混淆)。

因此,如果sizeof(TestObj)2,它将读取两个字节并将它们放入&(targetObj->data)指向的位置,不进行边界检查,并且不管您的体系结构endianess之间是否存在任何差异和文件协议endianess。请注意,这种方法不是一种独立于平台的解析包含二进制形式数字的文件的方法,因为与在文件中存储数据的方式相比,数字可能以不同的方式存储在您的计算机上(无论是谁设计了您正在尝试的二进制协议阅读)。

在C#中,您可以通过手动指定struct packing and field placement来实现类似的操作,尽管代码会遇到与C代码相同的问题。

答案 1 :(得分:1)

fread从流中的当前位置读取也见ftell和fseek。 C#中的等价物是Stream.Read

答案 2 :(得分:0)

来自man fread

 size_t
 fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);

 The function fread() reads nitems objects, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.

sizeof(short)由编译器根据https://stackoverflow.com/a/14171152/6204612

解析

C并没有对你做任何漂亮的转换。读取的内容是sizeof(short)字节,这些字节放入TestObj变量。是否正确是实施者的责任。您需要自己管理偏移量,集合大小等。