【问题标题】:What is the best way to write and append a large file in java在java中编写和附加大文件的最佳方法是什么
【发布时间】:2015-08-04 14:35:20
【问题描述】:

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

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

数据的总大小几乎是 4 GB,并且在 avg 上附加了大约 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 使用并作为实时存档。有没有更好的方法来实现这一点?

【问题讨论】:

  • 为什么要为每个单独的请求重新打开编写器?只需在 do-while 循环之前打开一次。不要忘记在 do-while 循环之后关闭它。

标签: java web-services hadoop filesystems hdfs


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    根据这个答案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 块后处理关闭编写器。这在 java 7 中可用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 2011-12-06
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 2011-06-15
      相关资源
      最近更新 更多