2017-12-26 12 views
2

저는 메모리에로드하지 않고 디스크에서 파일을 셔플하는 방법을 찾고 있습니다. 처음에는 그런 접근법이 존재하는지 의심 스럽지만 최근에 나는이 것을 발견했습니다. answer. 이 답변은 지원되지 않았거나 투표를 거치지 않았으므로이 코드가 실제로 메모리에로드하지 않고 파일을 셔플하는지 알고 싶습니다. 그렇다면 어떻게됩니까? 파일을 메모리에 처음로드하지 않고 어떻게 셔플 할 수 있는지 보지 못합니다!파일을 메모리에로드하지 않고 디스크에서 섞는 방법

+1

은 카드 더미를 섞은 것과 같습니다. 임의로 순서를 바꾸는 것 –

+1

파일을 완전히 읽지 않고 임의로 섞을 수 있습니다. 물론 일부 부품을 메모리로 읽어야합니다. –

답변

4

텍스트 파일에서 줄을 뒤섞는 것에 대해 가정한다고 가정합니다.

제이미 콕번 (Jamie Cockburn)의 링크 된 답변이 작동하는지는 잘 모르겠지만 제게는 완전히 합리적입니다. 메모리에 전체 파일을로드하지 않습니다

  • mmap하지만 당신이 목록이었다 것처럼 및 "을"바이트 "에서"를 통해 인덱싱하여 임의의 부분에 액세스 할 수 있습니다 : 아이디어는 다음과 같다 당신은 파일을 통해 두 번 가야합니까,하지만 당신은 메모리에 사용자가 파일을 통과
  • 처음으로 파일의 내용을로드하지 않는 메모리
  • 에로드, 당신은 라인 \n을 나누기 위해 밖으로보고 라인을하지 저장하지만, 각 행의 시작과 끝 주소에 해당하는 바이트 수 (또는 인덱스). 당신은 효과적으로
  • 이제 lines라는 인덱스의 목록 셔플 줄에 두 개의 번호를 저장
  • 지금 당신은 쓰기를위한 새 파일을 열고 단행 인덱스 반복 (기억을, 만 쌍 (int, int)을 포함); 각 인덱스 쌍에 대해 원래 파일의 한 줄인 data[start:end+1]을 메모리로 읽어 새 파일에 씁니다. 이 작업을 한 번 이상 메모리에 유지하지 마십시오.

이 접근법에서는 입력 파일의 행 수에 선형 메모리가 필요합니다. 평균 라인 길이가 두 개의 정수를 저장하는 데 필요한 메모리 양보다 큰 경우 전체 파일을 읽는 것보다 훨씬 작을 수 있습니다.

+0

예, 텍스트 파일에서 줄을 바 꾸었습니다. 고맙습니다. 잘 설명했다. – David