Ні, файл не читається автоматично в пам'ять, відкриваючи його. Це було б жахливо неефективно. sed
, наприклад, читає вхідний рядок за рядком, як і багато інших інструментів Unix. Рідко доводиться зберігати більше, ніж поточний рядок у пам'яті.
З awk
ним те саме. Він читає запис за один раз, який за замовчуванням є рядком. Якщо ви зберігаєте частини вхідних даних у змінних, це, звичайно, буде 1 .
Деякі люди мають звичку робити такі речі
for line in $(cat file); do ...; done
Оскільки оболонка буде мати розширення $(cat file)
повністю підстановки команд перед запуском навіть першої ітерації for
циклу, це буде читати весь file
в пам'яті (в пам'яті , використовуваної оболонкою , яка виконує for
петлю). Це трохи нерозумно, а також неелегантно. Натомість слід робити
while IFS= read -r line; do ...; done <file
Це буде обробляти file
по черзі (але читайте розуміння "IFS = read -r рядок" ).
Обробка файлів по черзі в оболонці потрібна лише рідко, оскільки більшість утиліт все одно орієнтована на рядки (див. Чому використання циклу оболонки для обробки тексту вважається поганою практикою? ).
Я працюю в галузі біоінформатики, і при обробці величезної кількості геномних даних я б не зміг зробити багато, якщо тільки не зберіг би в пам'яті лише ті біти даних, які були абсолютно необхідні. Наприклад, коли мені потрібно зняти біти даних, які можна було б використати для ідентифікації осіб із 1-терабайтного набору даних, що містять варіанти ДНК у файлі VCF (оскільки такий тип даних не може бути оприлюднений), я роблю рядок за рядком обробка за допомогою простої awk
програми (це можливо, оскільки формат VCF орієнтований на лінію). Я не читаю файл в пам'яті, обробляю його там і записую його знову! Якби файл був стиснутий, я би передавав його через zcat
або gzip -d -c
, який, оскільки gzip
здійснює потокову обробку даних, також не читав би весь файл у пам'ять.
Навіть у форматах файлів, не орієнтованих на рядки, як-от JSON чи XML, є потокові аналізатори, що дає можливість обробляти величезні файли, не зберігаючи їх у ОЗП.
З виконуваними файлами це трохи складніше, оскільки спільні бібліотеки можуть завантажуватися на вимогу та / або ділитися між процесами (див. , Наприклад, Завантаження спільних бібліотек та використання оперативної пам’яті , наприклад).
Кешування - це те, що я тут не згадував. Це дія використання оперативної пам'яті для зберігання часто доступних фрагментів даних. Менші файли (наприклад, виконувані файли) можуть кешуватися ОС, сподіваючись, що користувач зробить багато посилань на них. Окрім першого читання файлу, наступний доступ буде зроблений до оперативної пам’яті, а не до диска. Кешування, як буферизація вводу та виводу, зазвичай значною мірою прозоре для користувача, а обсяг пам'яті, який використовується для кешування речей, може динамічно змінюватися залежно від обсягу оперативної пам’яті, що виділяється програмами тощо.
1 Технічно більшість програм, ймовірно, читають шматок вхідних даних одночасно, або використовуючи явну буферизацію, або неявно через буферизацію, яку роблять стандартні бібліотеки вводу-виводу, а потім представляють цей фрагмент рядок за рядком до коду користувача. Набагато ефективніше читати кратний розмір блоку диска, ніж, наприклад, символ за один раз. Цей розмір шматка рідко буде більшим, ніж жменька кілобайт.