Não, um arquivo não é lido automaticamente na memória, abrindo-o. Isso seria terrivelmente ineficiente. sed
, por exemplo, lê sua entrada linha por linha, assim como muitas outras ferramentas Unix. Raramente tem que manter mais do que a linha atual na memória.
Com awk
é o mesmo. Ele lê um registro de cada vez, que por padrão é uma linha. Se você armazenar partes dos dados de entrada em variáveis, isso será extra, é claro 1 .
Algumas pessoas têm o hábito de fazer coisas como
for line in $(cat file); do ...; done
Desde que o shell terá de expandir a $(cat file)
substituição de comando completamente antes de executar até mesmo a primeira iteração do for
loop, este irá ler integralmente file
na memória (na memória usada pelo shell de executar o for
loop). Isso é um pouco bobo e também deselegante. Em vez disso, deve-se fazer
while IFS= read -r line; do ...; done <file
Isso processará file
linha por linha (mas leia Noções básicas sobre "IFS = leia -r linha" ).
Porém, raramente é necessário processar arquivos linha por linha no shell, pois a maioria dos utilitários é orientada a linhas (consulte Por que usar um loop do shell para processar o texto considerado uma má prática? ).
Estou trabalhando em bioinformática e, ao processar grandes quantidades de dados genômicos, não seria capaz de fazer muito, a menos que mantivesse apenas os bits dos dados que eram absolutamente necessários na memória. Por exemplo, quando preciso extrair os bits de dados que podem ser usados para identificar indivíduos de um conjunto de dados de 1 terabyte contendo variantes de DNA em um arquivo VCF (porque esse tipo de dados não pode ser tornado público), faço linha por linha processamento com um awk
programa simples (isso é possível, pois o formato VCF é orientado a linhas). Eu não ler o arquivo na memória, processá-lo lá, e escrevê-lo de volta novamente! Se o arquivo fosse compactado, eu o alimentaria através de , zcat
ou gzip -d -c
, que, como gzip
faz o fluxo de processamento de dados, também não leria o arquivo inteiro na memória.
Mesmo com formatos de arquivo que não são orientados a linhas, como JSON ou XML, existem analisadores de fluxo que permitem processar arquivos enormes sem armazenar tudo na RAM.
Nos executáveis, é um pouco mais complicado, pois as bibliotecas compartilhadas podem ser carregadas sob demanda e / ou compartilhadas entre processos (consulte Carregamento de bibliotecas compartilhadas e uso de RAM , por exemplo).
O armazenamento em cache é algo que não mencionei aqui. Esta é a ação de usar a RAM para armazenar dados acessados com freqüência. Arquivos menores (por exemplo, executáveis) podem ser armazenados em cache pelo sistema operacional na esperança de que o usuário faça muitas referências a eles. Além da primeira leitura do arquivo, os acessos subsequentes serão feitos à RAM e não ao disco. O armazenamento em cache, como o buffer de entrada e saída, geralmente é bastante transparente para o usuário, e a quantidade de memória usada para armazenar em cache as coisas podem mudar dinamicamente, dependendo da quantidade de RAM alocada pelos aplicativos etc.
1 Tecnicamente, a maioria dos programas provavelmente lê um pedaço dos dados de entrada de cada vez, usando buffer explícito ou implicitamente através do buffer que as bibliotecas de E / S padrão fazem, e então apresenta esse pedaço de linha por linha no código do usuário. É muito mais eficiente ler um múltiplo do tamanho do bloco do disco do que, por exemplo, um caractere de cada vez. Porém, esse tamanho de pedaço raramente será maior que um punhado de kilobytes.