поскольку 'fread' буферизован, необходимо ли сжимать данные в память и затем использовать их? - PullRequest
0 голосов
/ 06 марта 2012

Я использую fopen / fread / fwrite / fseek в Linux с gcc. необходимо ли выделить буфер памяти и использовать fread для последовательного считывания данных в буфер перед использованием данных?

Ответы [ 3 ]

2 голосов
/ 06 марта 2012

Когда вы используете fread или другие функции файлового ввода-вывода в стандартной библиотеке C, память буферизуется в нескольких местах.

  • Ваше приложение выделяет буфер, который передается в fread. fread копирует данные в ваш буфер, и затем вы можете делать с ним все, что хотите. Вы несете ответственность за распределение / освобождение этого буфера.
  • Библиотека C обычно создает буфер для каждого FILE*, который у вас открыт. Данные считываются в эти буферы большими кусками. Это позволяет fread удовлетворять множество небольших запросов без необходимости выполнять большое количество системных вызовов, которые являются дорогостоящими. Это то, что люди имеют в виду, когда говорят, что fread буферизовано.
  • Ядро также буферизует файлы, которые читаются в кеше диска. Это сокращает время, необходимое для системного вызова read, поскольку, если данные уже находятся в памяти, вашей программе не придется ждать, пока ядро ​​загрузит их с диска. Ядро будет удерживать недавно прочитанные файлы и может читать вперед для файлов, к которым осуществляется последовательный доступ.

Буфер библиотеки C выделяется автоматически при открытии файла и освобождается при закрытии файла. Вам совсем не обязательно с этим справляться.

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

2 голосов
/ 06 марта 2012

Вы должны передать буфер (буфер, созданный вашим кодом, malloced или local), чтобы перечитать, чтобы передать прочитанные данные вам. Я не знаю, что вы имеете в виду, говоря, что "хлеб в буфере". Большинство вызовов библиотеки «С» работают таким образом. Они не будут возвращать вам свое внутреннее хранилище (буферное или иное) и, если они это сделают, предоставят вам соответствующие функции освобождения / освобождения.

См. http://pubs.opengroup.org/onlinepubs/000095399/functions/fread.html Это также очень простой пример.

1 голос
/ 06 марта 2012

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

В некоторых специализированных случаях вы можете обрабатывать данные, не копируя их в пространство пользователя.См. Системный вызов sendfile , который напрямую копирует данные из одного дескриптора файла в другой.Это можно использовать для передачи данных из файла в сетевой сокет без чрезмерного копирования.

...