На практике вам обычно не нужно хранить все содержимое файла в памяти.Вы часто анализируете файл (особенно если он текстовый) или, по крайней мере, читаете файл небольшими порциями, и для этого он вам не нужен полностью в памяти.Для текстового файла достаточно часто читать его построчно (возможно, с некоторым состоянием внутри вашего анализатора) (используя fgets или getline ).
Файлы существуют (особенно на дисках или SSD с), потому что обычно они могут быть намного "больше", чем оперативная память вашего компьютера.На самом деле, файлы были изобретены (более 50 лет назад), чтобы иметь возможность обрабатывать данные больше памяти. Распределенные файловые системы также могут быть очень большими (и к ним можно получить удаленный доступ даже с ноутбука, например, NFS , CIFS и т. Д.)
Некоторые файловые системы способны хранить петабайты данных (на суперкомпьютерах) с отдельными файлами объемом в несколько терабайт (намного больше, чем доступная оперативная память).
Вы также, вероятно, будете использоватьнекоторые база данных с.У них обычно есть терабайты данных.См. Также этот ответ (о реалистичном размере sqlite
баз данных).
Если вы действительно хотите прочитать файл полностью в памяти, используя stdio (но вам следуетизбегайте этого, поскольку обычно вы хотите, чтобы ваша программа могла обрабатывать большое количество данных в файлах, поэтому чтение всего файла в памяти, как правило, является ошибкой проектирования), вы действительно можете зациклить fread (или fscanf или даже fgetc ) до конца файла.Обратите внимание, что feof полезен только после некоторой операции ввода.
На современных ноутбуках или настольных компьютерах вы можете (для эффективности) использовать буферы в несколько мегабайти, конечно, вы можете работать с большими файлами размером в несколько сотен гигабайт (намного больше, чем ваша RAM).
В файловых системах POSIX вы можете сделать IO с отображением памяти, например, mmap (2) - но это не может быть быстрее, чем read (2) с большими буферами (в несколько мегабайт).Вы можете использовать readahead (2) (для Linux) и posix_fadvise (2) (или madvise (2) при использовании mmap
) для настройки производительности с помощьюнамеки на вашу ОС ядро .
Если вам нужно написать код для Microsoft Windows, вы можете изучить его WinAPI и найти какой-то способ сделать памятьmapped IO.
На практике данные файлов (особенно если к ним обращались недавно) часто остаются в кеше page , что имеет первостепенное значение для производительности.Если это не так, то ваше оборудование (диск, контроллер и т. Д.) Становится узким местом, и ваша программа становится привязанной к вводу / выводу (в этом случае ни один программный трюк не может значительно улучшить производительность).