Unix-подобная система обычно имеет ограничение на количество дескрипторов файлов, открытых в любой момент времени; в моем Linux, например, в настоящее время это 1024, хотя я мог бы изменить его в разумных пределах. Но для этих ограничений есть веские причины, так как открытые файлы являются бременем для системы.
Вы еще не ответили на мой вопрос о том, есть ли несколько вхождений одного и того же ключа во входных данных, а это означает, что может потребоваться объединение нескольких отдельных пакетов данных в каждый файл. Если это не так, ответ Пейса будет самым лучшим, что вы можете сделать, поскольку всю эту работу необходимо выполнить, и нет смысла создавать огромную администрацию вокруг такой простой последовательности событий.
Но если в вашем вводе есть несколько сообщений для одного и того же ключа, было бы эффективно держать открытыми большое количество файлов. Однако я бы посоветовал не пытаться держать все 6000 открытыми одновременно. Вместо этого я бы выбрал что-то вроде 500, открытых в порядке живой очереди; то есть вы открываете файлы для первых 500 (или около того) отдельных ключей сообщений, а затем просматриваете весь входной файл в поисках материала, который можно добавить в эти 500, а затем закрываете их все при нажатии EOF при вводе. Вам также нужно будет сохранить HashSet
уже обработанных ключей, потому что затем вы снова перечитаете свой входной файл, обрабатывая следующую партию из 500 ключей, которые вы не уловили в первом раунде.
Обоснование: открытие и закрытие файла (обычно) является дорогостоящей операцией; вы НЕ хотите открывать и закрывать тысячи файлов более одного раза каждый, если можете помочь. Таким образом, вы держите как можно больше дескрипторов открытыми, и все они в конечном итоге заполняются за один проход через ваш ввод. С другой стороны, последовательная потоковая передача по одному входному файлу весьма эффективна, и даже если вам придется сделать 12 проходов по вашему входному файлу, время, необходимое для этого, будет практически незначительным по сравнению со временем, необходимым для открытия/закрытия 6000 других файлов. файлы.
Псевдокод:
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
}
person
Carl Smotricz
schedule
30.12.2009
000001
, и будет ли это означать, что 2-е и последующее вхождения должны быть объединены в файл000001.dat
? Это будет иметь значение для наиболее эффективной реализации. - person Carl Smotricz   schedule 30.12.2009