2015-05-22 6 views
2

У меня есть Java-программа, которая отправляет серию запросов GET в веб-службу и сохраняет тело ответа в виде текстового файла.Каков наилучший способ записи и добавления большого файла в java

Я реализовал следующий пример кода (отфильтровал большую часть кода, чтобы выделить заинтересованного), который добавляет текстовый файл и записывает в качестве новой строки в EOF. Однако код работает отлично, но производительность страдает по мере увеличения размера файла.

Общий размер данных составляет почти 4 ГБ и составляет около 500 КБ до 1 МБ данных в средн.

do{ 
     //send the GET request & fetch data as string 
     String resultData = HTTP.GET <uri>; 

     // buffered writer to create a file 
     BufferedWriter writer = new BufferedWriter(new FileWriter(path, true)); 

     //write or append the file 
     writer.write(resultData + "\n"); 
    while(resultData.exists()); 

Эти файлы создаются на ежедневной основе, и переехал в HDFS для потребления Hadoop и в реальном виде - времени архива. Есть ли лучший способ достичь этого?

+1

Почему вы повторно открываете автора для каждого индивидуального запроса? Просто откройте его один раз, перед циклом do-while. Не забудьте закрыть его после цикла while-while. – Gimby

ответ

3

1) Вы открываете новый writer каждый раз, не закрывая предыдущий объект writer.

2) Не открывайте файл для каждой операции записи, а открывайте его перед циклом и закрывайте его после цикла.

BufferedWriter writer = new BufferedWriter(new FileWriter(path, true)); 
do{ 
      String resultData = HTTP.GET <uri>; 
      writer.write(resultData + "\n"); 
}while(resultData.exists()); 
writer.close(); 

3) По умолчанию буферизованный размер BufferedWriter 8192 символов, Поскольку у вас есть 4 ГБ данных, я бы увеличить размер буфера, чтобы улучшить производительность, но в то же время, убедитесь, что ваш JVM имеет достаточно памяти для удерживайте данные.

BufferedWriter writer = new BufferedWriter(new FileWriter(path, true), 8192 * 4); 
do{ 
      String resultData = HTTP.GET <uri>; 
      writer.write(resultData + "\n"); 
}while(resultData.exists()); 
writer.close(); 

4) Так как вы делаете вызов веб-службы GET, производительность зависит от response времени webservice также.

0

В соответствии с этим ответом Java difference between FileWriter and BufferedWriter то, что вы делаете прямо сейчас, неэффективно.

Предоставленный вами код является неполным. Скобки отсутствуют, нет close Заявление для писателя. Но если я правильно понимаю, для каждого resultData вы открываете новый буферный писатель и вызываете запись один раз. Это означает, что вы должны использовать FileWriter напрямую, так как, как вы это делаете, буфер - это просто накладные расходы.

Если то, что вы хотите, чтобы получить данные в цикле и записать их в одном файле, то вы должны сделать что-то вроде этого

try(BufferedWriter writer = new BufferedWriter(new FileWriter("PATH_HERE", true))) { 
    String resultData = ""; 

    do { 
     //send the GET request & fetch data as string 
     resultData = HTTP.GET <uri>; 

     //write or append the file 
     writer.write(resultData + "\n"); 

    } while(resultData != null && !resultData.isEmpty()); 

} catch(Exception e) { 
    e.printStackTrace(); 
} 

выше использует try with resources, который будет обрабатывать закрытие писателя после выхода блок try. Это доступно в java 7.