Есть ли способ открыть файл, который позволяет мне редактировать всего несколько байтов? - PullRequest
1 голос
/ 30 ноября 2011

Я пишу класс, который сжимает двоичные данные с использованием потока zlib.У меня есть буфер, который я заполняю потоком вывода, и как только он заполняется, я выгружаю буфер в файл, используя fopen(filename, 'ab');... Это означает, что моя программа открывает файл для записи только тогда, когда у него заполнен буферданных для сброса, он идет и делает это и сразу же закрывает его.

Проблема в моем формате. Я использую 8-байтовый заголовок в начале каждого файла, который содержит исходную длину и сжатую длину, но я не знаю этих значений до конца всего процесса сжатия.

Я хотел написать 8 байтов нулей, затем добавить все мои сжатые данные, а затем вернуться в конце во время очистки, чтобы заполнить эти 8 байтов данными о размере, но я не могупохоже, что есть способ открыть файл, не возвращая его обратно в память.Я просто хочу отредактировать первые 8 байтов файла.Нужно ли использовать mmap?

Ответы [ 3 ]

3 голосов
/ 30 ноября 2011

Поскольку вы используете файл в режиме добавления, вам нужно закрыть и снова открыть его:

  1. открыть с fopen(filename, "r+b");
  2. записать 8 байтов;
  3. закройте файл, используя fclose().

r+ означает

Открыт для чтения и письма. Поток расположен на начало файла.

и b необходимо открыть в двоичном режиме.

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

1 голос
/ 30 ноября 2011

Если у вас есть гибкость в изменении вашего формата, я мог бы предложить это. Определите сжатый поток так, чтобы он представлял собой последовательность с неизвестным числом блоков, и каждому блоку предшествует целое число фиксированной длины, указывающее количество байтов в блоке. Поток заканчивается, когда следующий блок имеет размер ноль.

Недостаток этого формата в том, что у читателя потока нет возможности узнать, сколько данных поступает, пока они все не будут прочитаны. Но преимущество в том, что он избегает проблемы, которую вы пытаетесь решить.

Что еще более важно, он позволяет вам отправлять сжатый поток данных куда-то, когда вы читаете ввод, и вам не нужно сохранять все это перед отправкой. Например, вы можете написать сжатый Unix-фильтр, который вы можете поместить в конвейерный поток:

prog1 | yourprog -compress | rsh host yourprog -expand | prog2

Удачи.

1 голос
/ 30 ноября 2011

Используйте rewind(), чтобы вернуть указатель файла в начало файла после того, как вы записали последние несколько байтов данных.Затем вы можете вывести 8 байтов информации о длине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...