2014-11-22 4 views
-2

У меня есть программа Java, что делает этот алгоритм:Многопоточность нескольких файлов

Given a directory. 
For each file in the directory. 
    read each line 
     process the line with regex and other string operation in addition to parsing 
     write the line after processing to an output file 

Каталог имеет около 10 файлов с около 3 миллионов строк.

Обработка детали кажется узким местом в производительности из-за сложности регулярного выражения и еще медленнее с парсинговой частью. , так как у меня есть мощная машина с большим количеством плунжера и, как указано в «cat/proc/cpuinfo | grep processor wc -l», содержит 16 процессоров. Было бы грустно не привлекать их к участию.

Моя идея - сначала прочитать все файлы в одном списке массивов. Затем разделите список на список вспомогательных массивов, равный количеству требуемых потоков. После запуска потоков каждый поток с данным подсписком должен делать обрабатывающей частью одновременно и сохранять вывод в новый подмассив, который в конце должен быть объединен и сброшен в выходной файл.

Является ли это правильным способом решения такой проблемы?

Любые ссылки на другие подобные работы были бы оценены.

Большое спасибо.

String dir = "path/to/dir"; 
    File folder = new File(dir); 
    if (folder.isDirectory()) { 
     File[] listOfFiles = folder.listFiles(); 
     for (int i = 0; i < listOfFiles.length; i++) { 
      File file = listOfFiles[i]; 
      if (file.isFile() && file.getName().contains("log")) { 
       System.out.println("processing file: " + file); 
       test.readFile(file); 
      } 
     } 
    } 
} 

PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output), StandardCharsets.UTF_8), true); 
public void readFile(File file) { 
    FileInputStream fis = null; 
    BufferedReader br = null; 
    String line; 

    try { 
     fis = new FileInputStream(file); 
     br = new BufferedReader(new InputStreamReader(fis, 
       Charset.forName("UTF-8"))); 
     while ((line = br.readLine()) != null) { 
      String processedLine = processingLine(line); 
      if (processedLine != null){ 
       pw.println(processedLine); 
      } 

     } 

    } catch (IOException e) { 

    } 
} 

public String processingLine(String line) { 
    //regex 
    //string operations 
    //parsing text 
} 
+0

каждый входной файл получает собственный выходной файл? или они имеют один выходной файл? – MeBigFatGuy

+0

Было бы намного проще, если бы программа Java выполнила ровно 1 файл последовательно и запустила копию программы для каждых 10 файлов. – Joni

+2

Я очень удивлен, что синтаксический анализ строки настолько медленный. Как выглядит код регулярного выражения/разбора? Кажется, вы повторяете один и тот же шаблон каждый раз, когда метод вызывается (так, миллионы раз) вместо повторного использования. Это плохая идея. Для такого кода, если он правильно закодирован, я ожидал бы, что IO будет ограничивающим фактором. Первый совет: используйте BufferedWriter. –

ответ

0
  • Используйте java.util.concurrency.Executors нереститься дочерних потоков для каждой обработки файлов;
  • использовать синхронизированную очередь для сбора результата;
  • процесс собирает очередь в отдельном потоке, чтобы записать ваши данные (безопасный & неповрежденный).
Смежные вопросы