如果我想访问文件中的不同信息,是否必须多次 fseek?

Do I have to fseek several times if I want to access different piece of information in a file?

At fixed locations in the file metadata, there are three important integers, each stored using exactly 4 bytes:

At byte offset 10-13, the offset in the bitmap file where the pixel array starts.

At byte offset 18-21, the width of the image, in pixels.

At byte offset 22-25, the height of the image, in pixels.

/*
 * Read in the location of the pixel array, the image width, and the image
 * height in the given bitmap file.
 */
void read_bitmap_metadata(FILE *image, int *pixel_array_offset, int *width, int *height) {

    fseek(image, 10, SEEK_SET);
    fread(pixel_array_offset, 4, 1, image);
    fseek(image, 18, SEEK_SET);
    fread(width, 4, 1, image);
    fseek(image, 22, SEEK_SET);
    fread(height, 4, 1, image);

}

我这里是不是要用3次fseek,还要注意宽度和高度是连续的?

不,你可以省略最后一个fseek()

fread() 文件位置总是按读取的数据量前进。所以你只需要 fseek() 当你想跳过一些字节或者当你想寻找到一个固定的位置并且你不关心你现在在哪里。

由于您只跳过几个字节,因此您也可以只从 26 字节的偏移量 0 中执行单个 fread() 到缓冲区中,然后根据需要从缓冲区中选取数据。

字节序警告:从文件读取多字节整数时存在一个大问题:这是否有效取决于文件字节序和主机字节序.您的代码只有在它们匹配时才有效。如果它们不匹配,则必须在 fread() 操作后交换字节。在 Linux 上你有 bswap_32() ,或者如果文件中的字节顺序是 big endian (又名 网络字节顺序 ) 你可以使用 ntohl().

如果您使用的是现代 OS(具有虚拟内存),则可以使用 mmap 将文件映射到内存(不是复制,它使用虚拟内存)。这将允许您使用内存操作读取/(可选写入)和查找:C 中的指针算术/数组。

对于 Unix(Gnu/Linux、MacOS、BSD、System V),参见 https://en.wikipedia.org/wiki/Mmaphttp://man7.org/linux/man-pages/man2/mmap.2.html

我想现在连微软的Windows都可以做到了,看https://docs.microsoft.com/en-gb/windows/desktop/Memory/file-mapping