在 java 中写入和附加大文件的最佳方法是什么

What is the best way to write and append a large file in java

我有一个 java 程序,它向网络服务发送一系列 GET 请求并将响应正文存储为文本文件。

我已经实现了以下示例代码(过滤了大部分代码以突出显示相关内容),它附加了文本文件并在 EOF 处作为新行写入。然而,该代码可以完美运行,但随着文件大小的增加,性能会受到影响。

数据总大小将近 4 GB,平均每 1 MB 数据附加约 500 KB。

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 使用并作为实时存档。有没有更好的方法来实现这个?

根据这个答案Java difference between FileWriter and BufferedWriter你现在所做的事情效率低下。

您提供的代码不完整。缺少括号,作者没有 close 声明。但是,如果我对每个 resultData 的理解正确,您将打开一个新的缓冲写入器并调用 write once 。这意味着你应该直接使用 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 中可用。

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 网络服务调用,因此性能还取决于 webserviceresponse 时间。