유닉스 계열 시스템은 일반적으로 주어진 시간에 열려있는 파일 핸들 수에 제한이 있습니다. 내 리눅스에서, 예를 들어, 그것은 현재 1024에 있지만 이유 중에 그것을 바꿀 수는 있습니다. 그러나 열린 파일이 시스템에 부담이되기 때문에 이러한 제한에 대한 충분한 이유가 있습니다.
입력에 동일한 키가 여러 번 발생했는지 여부에 대한 내 질문에 아직 답하지 않았습니다. 즉, 데이터의 여러 개별 일괄 처리를 각 파일에 연결해야 할 수 있습니다. 이것이 사실이 아니라면, Pace의 대답은 당신이 할 수있는 최선의 일일 것입니다. 모든 일이 끝나야하며 그러한 단순한 일련의 사건들에 대해 거대한 행정을 세우는 데는 아무런 의미가 없습니다.
동일한 키에 대한 입력에 여러 메시지가있는 경우 많은 수의 파일을 열어 두는 것이 효율적입니다. 그래도 모든 6000을 한 번에 열어 놓으려고하지 말라고 조언합니다. 대신, 나는 선착순으로 열리는 500과 같은 것을 갈 것입니다. 즉, 처음 500 개의 메시지 키를 열어 파일을 열어 전체 입력 파일을 씹어 500 개에 추가 할 항목을 찾은 다음 입력시 EOF를 치면 모두 닫습니다. 키의 HashSet
을 계속 처리해야합니다. 입력 파일을 다시 읽으므로 첫 번째 라운드에서 포착하지 못한 다음 키 500 개를 처리해야하기 때문입니다.
이론적 설명 : 파일 열기 및 닫기는 비용이 많이 드는 작업입니다. 도움이 될만한 파일을 여러 번 열거 나 닫고 싶지는 않습니다. 따라서 가능한 한 많은 핸들을 열어두면 모두 입력을 통해 단일 패스로 채워집니다. 반면에 하나의 입력 파일을 순차적으로 스트리밍하는 것은 매우 효율적입니다. 입력 파일을 12 번 통과해야하더라도 시간은 여섯 번 열고 닫는 데 필요한 시간에 비해 거의 무시할 수 있습니다 파일.
의사 코드 :
processedSet = [ ]
keysWaiting = true
MAXFILE = 500
handlesMap = [ ]
while (keysWaiting) {
keysWaiting = false
open/rewind input file
while (not EOF(input file)) {
read message
if (handlesMap.containsKey(messageKey)) {
write data to handlesMap.get(messageKey)
} else if (processedSet.contains(messageKey) {
continue // already processed
} else if (handlesMap.size < MAXFILE) {
handlesMap.put(messageKey, new FileOutputStream(messageKey + ".dat")
processedSet.add(messageKey)
write data to handlesMap.get(messageKey)
else
keysWaiting = true
endif
}
for all handlesMap.values() {
close file handle
}
handlesMap.clear
}
우려되는 점은 무엇입니까? – OscarRyz
"효율적인"이란 무엇을 의미합니까? 프로세스에 소요되는 시간을 최적화하려고하십니까? 기억의 양? 파일 시스템에서 개별 읽기 수? 각 출력 파일이 디스크에 기록되는 횟수? 이것을 알면 답을 유도하는 데 도움이됩니다. – delfuego
입력 파일에 '000001'이 여러 번 나타날지 여부를 지정하십시오. 그리고 두 번째 및 다음 번 발생을 의미하는지 여부는 데이터를 '000001.dat' 파일에 연결해야합니까? 이는 가장 효율적인 구현이 무엇이 다른지를 결정합니다. –