Non, un fichier n'est pas lu automatiquement en mémoire en l'ouvrant. Ce serait terriblement inefficace. sed
, par exemple, lit son entrée ligne par ligne, comme le font de nombreux autres outils Unix. Il doit rarement conserver plus que la ligne actuelle en mémoire.
Avec awk
c'est la même chose. Il lit un enregistrement à la fois, qui par défaut est une ligne. Si vous stockez des parties des données d'entrée dans des variables, ce sera supplémentaire, bien sûr 1 .
Certaines personnes ont l'habitude de faire des choses comme
for line in $(cat file); do ...; done
Étant donné que le shell devra étendre la $(cat file)
substitution de commande complètement avant d' exécuter même la première itération de la for
boucle, ce sera lu toute la file
en mémoire (dans la mémoire utilisée par le shell d' exécuter la for
boucle). C'est un peu idiot et aussi inélégant. Au lieu de cela, on devrait faire
while IFS= read -r line; do ...; done <file
Cela traitera file
ligne par ligne (mais lisez bien Comprendre "IFS = read -r line" ).
Le traitement des fichiers ligne par ligne dans le shell n'est cependant que rarement nécessaire, car la plupart des utilitaires sont de toute façon orientés ligne (voir Pourquoi l'utilisation d'une boucle shell pour traiter du texte est-elle considérée comme une mauvaise pratique? ).
Je travaille en bioinformatique, et lors du traitement d'énormes quantités de données génomiques, je ne serais pas en mesure de faire grand-chose à moins de ne conserver que les bits des données qui étaient absolument nécessaires en mémoire. Par exemple, lorsque j'ai besoin de supprimer les bits de données qui pourraient être utilisés pour identifier des individus d'un ensemble de données de 1 téraoctet contenant des variantes d'ADN dans un fichier VCF (car ce type de données ne peut pas être rendu public), je le fais ligne par ligne traitement avec un awk
programme simple (ceci est possible car le format VCF est orienté ligne). Je ne lis pas le fichier en mémoire, je ne le traite pas et je le réécris! Si le fichier était compressé, je le ferais passer zcat
ou gzip -d -c
, qui, depuis le gzip
traitement en continu des données, ne lirait pas non plus le fichier entier en mémoire.
Même avec des formats de fichiers qui ne sont pas orientés ligne, comme JSON ou XML, il existe des analyseurs de flux qui permettent de traiter des fichiers énormes sans tout stocker dans la RAM.
Avec les exécutables, c'est un peu plus compliqué car les bibliothèques partagées peuvent être chargées à la demande et / ou être partagées entre les processus (voir Chargement des bibliothèques partagées et utilisation de la RAM , par exemple).
La mise en cache est quelque chose que je n'ai pas mentionné ici. Il s'agit de l'utilisation de la RAM pour stocker des données fréquemment consultées. Les fichiers plus petits (par exemple les exécutables) peuvent être mis en cache par le système d'exploitation dans l'espoir que l'utilisateur leur fera de nombreuses références. Outre la première lecture du fichier, les accès ultérieurs seront effectués sur la RAM plutôt que sur le disque. La mise en cache, comme la mise en mémoire tampon des entrées et des sorties, est généralement largement transparente pour l'utilisateur et la quantité de mémoire utilisée pour mettre en cache les choses peut changer dynamiquement en fonction de la quantité de RAM allouée par les applications, etc.
1 Techniquement, la plupart des programmes lisent probablement une partie des données d'entrée à la fois, soit en utilisant une mise en mémoire tampon explicite, soit implicitement via la mise en mémoire tampon des bibliothèques d'E / S standard, puis en présentant cette partie ligne par ligne au code de l'utilisateur. Il est beaucoup plus efficace de lire un multiple de la taille de bloc du disque que par exemple un caractère à la fois. Cependant, cette taille de bloc sera rarement supérieure à une poignée de kilo-octets.