如何使用Java编写和附加大型文件是最佳方式?

3
我有一个Java程序,向Web服务发送一系列GET请求,并将响应正文存储为文本文件。
我实现了以下示例代码(过滤了大部分代码以突出相关内容),该代码将文本文件追加并在EOF处写入新行。但是,随着文件大小的增加,性能会受到影响,尽管代码完美运行。
数据总大小约为4GB,平均每次追加500KB至1MB的数据。
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 循环之前打开它一次。不要忘记在 do-while 循环后关闭它。 - Gimby
2个回答

4

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个字符,由于你有4GB的数据,建议将缓冲区大小增加,以提高性能,但同时确保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服务调用,因此性能取决于webserviceresponse时间。


我想为了安全起见(以防电源中断),每次都要打开文件,那么这种情况的解决方案是什么?FileWriter是否需要读取整个文件才能在末尾添加新内容? - user924

0
根据这个答案 Java difference between FileWriter and BufferedWriter,你现在所做的是低效的。
你提供的代码不完整,括号丢失,没有写入器的close语句。但是如果我理解正确,对于每个resultData,你都会打开一个新的缓冲写入器并调用一次write。这意味着应该直接使用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 块后自动关闭 writer。这个特性在 Java 7 中可用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接