我有一个java程序,它向Web服务发送一系列GET请求,并将响应主体存储为文本文件。
我已经实现了以下示例代码(过滤了大部分代码以突出显示相关内容),它附加了文本文件并在EOF中作为新行写入。然而,代码工作得很好,但随着文件大小的增大,性能会受到影响。
数据的总大小几乎为4 GB,平均附加大约500 KB到1 MB的数据。
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消费和作为实时存档。有没有更好的方法来实现这一目标?
答案 0 :(得分: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 GB的数据,我会增加缓冲区大小,以提高性能但同时确保你的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 Web服务呼叫,因此性能也取决于response
的{{1}}时间。
答案 1 :(得分: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中可用。