【问题标题】:Java BufferedWriter very slow - 300 MB of dataJava BufferedWriter 非常慢 - 300 MB 数据
【发布时间】:2015-03-28 12:53:55
【问题描述】:

我正在逐行读取由固定长度记录组成的文本文件,并附加一些值,然后写入另一个文件。

像往常一样,我使用 BufferedWriter,发现读取、附加值和写入另一个文件大约需要 20 分钟。

BufferedWriter br = new BufferedReader(new FileReader(infile));
if (br != null) {
    for (String line; (line= br.readLine()) != null;) {
        i= i+ 1;
        line += "    " + String.format("%09d", i) + "S";
        try {
            bw = new BufferedWriter(new FileWriter("out.txt",
                    true));
            bw.write(line);
            bw.newLine();
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

这是我使用的代码。读取整个文件并附加值只需 7 秒,但写入文件似乎很慢。我知道 BufferedWriter 不可能这么慢。我没有增加缓冲区大小,因为我正在逐行阅读,出于同样的原因没有尝试 nio。

建议我一些提高速度的方法?

【问题讨论】:

  • 您需要创建一个新的缓冲写入器,通过它为您处理的每一行输入打开和关闭一个文件写入器?
  • 你每行都重新打开文件...怎么样,在循环之前打开一次?

标签: java


【解决方案1】:

您正在创建一个新的缓冲写入器,然后通过它为您处理的每一行输入打开和关闭一个文件写入器。

相反,在 for 循环之前创建 bw 并在之后关闭它。

【讨论】:

    【解决方案2】:

    你有至少两个问题:

    • 您将在每次迭代时重新打开输出文件。这几乎肯定会很慢。在打开阅读器的同时打开一次。
    • 您没有在异常情况下关闭阅读器或编写器。使用try-with-resources 块(Java 7)或try/finally 块(Java 7 之前)

    后者不会是性能问题,但它可能会破坏其他期望文件关闭的代码。

    此外,我强烈建议不要使用FileReaderFileWriter,因为两者都使用平台默认编码,而无需您指定任何其他内容。如果您使用的是 Java 7,请使用 Files.newBufferedReaderFiles.newBufferedWriter 其中:

    • 代码更短
    • 默认使用 UTF-8(这通常是最好的选择)
    • 如果您需要其他内容,请允许您指定编码

    【讨论】:

    • @StephenC 更新了问题。对不起。
    • @JonSkeet 我必须使用 Java 6。
    • @Harbinger:请在以后的问题中注意这一点。除非另有说明,否则答案可能越来越多地假设 Java 7+ - 毕竟它是在 2011 年发布的。 (我强烈建议推动升级,单独说明...)
    • @JonSkeet 当然是乔恩。感谢您的来信。
    • TBH,截至 2015 年 5 月,我很想假设 Java 8
    【解决方案3】:

    有两个原因使您的代码运行缓慢:

    1. 每次写入一行时,您都会创建文件outputstream
    2. 您使用 BufferedReader 和 BufferedWriter 逐行读写

    试试这个代码:

    public void copyFile() throws IOException{
        FileInputStream fis = new FileInputStream(new File("in.txt"));
        FileOutputStream fos = new FileOutputStream(new File("out.txt"));
        byte[] buffer = new byte[1024];
        int len;
        while((len = fis.read(buffer)) != -1){
            fos.write(buffer, 0, len);
        }
        fos.close();
        fis.close();
    }
    

    使用FileInputStreamFileOutputStreambuffer,您可以通过增加或减少buffer 的大小来控制您的读写速度。

    【讨论】:

      猜你喜欢
      • 2014-11-05
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多