2010-12-26 2 views
2

Мне нужно решить проблему, близкую к разбору огромного файла, например, 3 ГБ или выше. Ну, файл структурирован как псевдо XML-файл, как:Продюсер/Потребительский образец Java-путь

<docFileNo_1> 
<otherItems></otherItems> 
<html> 
<div=XXXpostag> 
</html> 

</docFileNo> 
    ... others doc... 
<docFileNo_N> 
<otherItems></otherItems> 

<html> 
<div=XXXpostag> 
</html> 

</docFileNo> 

....... 

В недавнем сообщении: "http://stackoverflow.com/questions/4355107/parsing-a-big-big-not-well- сформирован-файл-с-Явы», я обнаружил интересное решение моей проблемы .. Так что я думал, чтобы осуществить свою заявку парсер как многопоточные:

  1. После собирать в strinbUilder текстового контекст с тегом до < \ html>, я возвращаю Stringbuilder.
  2. После возврата Stringbuilder я извлекаю текстовое содержимое html-страницы через CSS-правила. Я получаю это с помощью анализатора html, JSOUP http://jsoup.org/. После извлечения содержимого html-страницы я должен сохранить это содержимое в файле.

Так .. Поместите свое внимание на шаге 1) и 2), я думаю, чтобы отделить sequencial шаблон с многопоточной способом, как:

  1. После прочтения кусок файла (построчно line до получения от .. до < \ html>), я добавляю строку в Stringbuilder.
  2. Для StringBuilder я создаю поток, поддерживающий код до . 2.1. Разберите html и извлеките текстовое содержимое. 2.2 Сохраните текстовое содержимое в файле.

Так у меня есть сомнения ..

  1. Сколько Нити я должен создать ?? Возможно ли, что я должен создать поток для всех созданных Stringbuilder? Это не проблема памяти?
  2. Как я могу сделать, чтобы получить точное количество потоков, которые хорошо работали?
  3. Как я могу узнать, сколько потоков закончилось? Я должен ждать, что все потоки закончатся, чтобы прекратить мою работу?

Для моих сомнений ... точка 1, я не знаю, как это реально решить. Для точки 2 я думаю, что я мог бы реализовывать потоки, такие как внутренний класс класса, который анализирует файл, и поэтому у меня может быть статический счетчик, увеличенный по завершенным потокам. Что касается пункта 3, я думаю, что это аналогичная точка 2, но я не знаю, как это сделать. Подождите мое приложение ....

Кто-нибудь может мне предложить что-нибудь, чтобы разрешить мои сомнения? thanks :)

+0

Пожалуйста, прекратите кричать. – Oswald

+0

Я чувствую, что название несколько вводит в заблуждение. Я думал, вы спросите что-то, связанное с обменом сообщениями или Design Pattern. – chris

+1

Я сделал что-то очень похожее, разобрав огромные файлы «кусками», а затем потребляя куски с помощью нескольких потоков (кроме того, что мой парсер был очень сложным и, следовательно, довольно медленным). В основном то, что хорошо работает, - это адаптировать количество потоков к числу доступных (виртуальных) ЦП. Если у вас двухъядерный процессор, в большинстве случаев бессмысленно иметь два или более потребительских потока. Если, с другой стороны, у вас есть 16 виртуальных ядер, вам может понадобиться около 16 потребительских потоков. – SyntaxT3rr0r

ответ

1

Если у вас есть достойный, эффективный парсер, он должен быть способен анализировать данные так быстро, как вы можете их прочитать. Я предлагаю вам убедиться, что это так, и вы сможете использовать один поток (возможно, отдельный для чтения).

3 GB не так уж и велика. Вы должны уметь читать/разбирать его через минуту. Большая часть этого времени будет просто читать файл с диска. Стоимость, скорее всего, будет тем, что вы делаете с анализируемой информацией, и это значит, что вам стоит перейти к одному или нескольким дополнительным потокам.

Чтобы связать данные между двумя потоками (один для чтения, один для обработки), вы можете использовать либо Exchange, либо PipedOutputStream/PipedInputStream.Теплообменник более эффективен, но поток Piped легче интегрировать с парсером.

+0

Если есть голосующий голос, я хотел бы узнать, почему это было сделано. Любой голос, который я могу узнать, также приветствуется. –

+0

@ peter- Не может помочь вам с downvote, но 3G - это огромный огромный текстовый файл в моем мире. И это займет много времени, чтобы прочитать его. Некоторые синтаксические анализаторы (типа, которые хотели бы сохранить дерево в памяти) захлестнули бы его. –

+0

Для моих целей 3GB слишком велико, потому что вся операция, которую я здесь объяснил, занимает несколько секунд: (... потому что нужно проанализировать более 50 TERA документов, подобных тому, что я описал ранее. – Bomberlatinos9

Смежные вопросы