아니요, 파일을 열어 메모리에 파일을 자동으로 읽지 않습니다. 그것은 끔찍하게 비효율적입니다. sed
예를 들어 다른 많은 유닉스 도구와 마찬가지로 입력을 한 줄씩 읽습니다. 메모리에 현재 행보다 많은 것을 유지해야하는 경우는 거의 없습니다.
로 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 line"이해 참조).
어쨌든 대부분의 유틸리티는 줄 지향적이므로 쉘에서 한 줄씩 파일을 처리하는 것은 거의 필요하지 않습니다 ( 쉘 루프를 사용하여 텍스트를 나쁜 습관으로 간주하는 이유는 무엇입니까? 참조 ).
나는 생물 정보학에서 일하고 있으며 대량의 게놈 데이터를 처리 할 때 절대적으로 필요한 데이터를 메모리에 보관하지 않으면 많은 것을 할 수 없습니다. 예를 들어, VCF 파일에 DNA 변형이 포함 된 1 테라 바이트 데이터 세트에서 개인을 식별하는 데 사용할 수있는 데이터 비트를 제거해야하는 경우 (데이터 유형을 공개 할 수 없기 때문에) 한 줄씩 간단한 awk
프로그램으로 처리 (VCF 형식은 라인 지향적이므로 가능합니다). 나는 하지 않는 메모리로 파일을 읽을 그것을 거기를 처리하고 다시 밖으로 다시 쓰기! 파일이 압축 된 경우, 나는 그것을 통해 공급 것 zcat
또는 gzip -d -c
이후하는, gzip
데이터 스트림 처리를 수행, 또한 메모리에 전체 파일을 읽을 것이다.
JSON 또는 XML과 같이 라인 지향 이 아닌 파일 형식의 경우에도 파일을 모두 RAM에 저장하지 않고도 대용량 파일을 처리 할 수있는 스트림 파서가 있습니다.
실행 파일을 사용하면 공유 라이브러리가 요청시로드되거나 프로세스간에 공유 될 수 있으므로 약간 더 복잡합니다 ( 예 : 공유 라이브러리로드 및 RAM 사용량 참조 ).
캐싱은 여기서 언급하지 않은 것입니다. RAM을 사용하여 자주 액세스하는 데이터를 보관하는 작업입니다. 더 작은 파일 (예 : 실행 파일)은 사용자가 많은 참조를 할 수 있도록 OS에서 캐시 할 수 있습니다. 파일을 처음 읽은 것 외에도 디스크가 아닌 RAM에 대한 후속 액세스가 이루어집니다. 입력 및 출력의 버퍼링과 같은 캐싱은 일반적으로 사용자에게 크게 투명하며 사물을 캐시하는 데 사용되는 메모리의 양은 응용 프로그램 등에 의해 할당 된 RAM의 양에 따라 동적으로 변경 될 수 있습니다.
1 기술적으로 대부분의 프로그램은 명시 적 버퍼링을 사용하거나 표준 I / O 라이브러리가 수행하는 버퍼링을 통해 암시 적으로 한 번에 입력 데이터 청크를 읽은 다음 해당 청크를 한 줄씩 사용자 코드에 표시합니다. 한 번에 한 문자보다 여러 개의 디스크 블록 크기를 읽는 것이 훨씬 더 효율적입니다. 이 청크 크기는 소수 킬로바이트보다 크지 않습니다.