Нужно ли искать несколько раз, если я хочу получить доступ к другой части информации в файле? - PullRequest
0 голосов
/ 09 февраля 2019

В фиксированных местах в метаданных файла есть три важных целых числа, каждое из которых хранится с использованием ровно 4 байтов:

С байтовым смещением 10-13, смещение в файле битовой карты, где находится массив пикселейначинается.

По байтовому смещению 18-21 - ширина изображения в пикселях.

По байтовому смещению 22-25 - высота изображения в пикселях.

/*
 * 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);

}

Должен ли я использовать fseek 3 раза здесь, даже заметить, что ширина и высота постоянно?

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Если вы используете современную ОС (которая имеет виртуальную память), то вы можете использовать mmap, чтобы отобразить файл в память (не для копирования, он использует виртуальную память).Это позволит вам читать / (опционально записывать) и искать, используя операции с памятью: арифметика / массивы указателей в C.

Для Unix (Gnu / Linux, MacOS, BSD, System V) см. https://en.wikipedia.org/wiki/Mmap и http://man7.org/linux/man-pages/man2/mmap.2.html

Я думаю, что теперь даже Windows от Microsoft может сделать это, см. https://docs.microsoft.com/en-gb/windows/desktop/Memory/file-mapping

0 голосов
/ 09 февраля 2019

Нет, вы можете опустить последние fseek().

. fread() всегда увеличивает позицию файла на количество прочитанных данных.Так что вам нужно fseek(), только когда вы хотите пропустить несколько байтов или когда вы хотите искать фиксированную позицию, и вам все равно, где вы находитесь в данный момент.

Поскольку вы пропускаете только несколько байтов, вы также можете просто сделать один fread() со смещением 0 из 26 байтов в буфер и затем выбрать данные из буфера по мере необходимости.

Предупреждение о порядке байтов: Существует одна большая проблема при чтении многобайтовых целых чисел из файла: работает ли это или нет, зависит от порядкового номера файла и от порядкового номера узла.Ваш код работает только тогда, когда они совпадают.Если они не совпадают, вы должны поменять местами байты после операции fread().В Linux у вас есть bswap_32() для этого, или если порядковый номер в файле big endian (он же сетевой порядок байтов ), вы можете использовать ntohl().

...