如何在Java中附加/写入大量数据文件文本

hud*_*udi 6 java file

我有一个150k记录的数据库.我想尽快写这个文件.我尝试了很多方法,但看起来都很慢.如何让它更快?

我用40k的块读了这些记录.所以首先我读40k然后再读40k等等.

读取记录后,此过程返回一个包含40k行的StringBuilder.然后我们将这个StringBuilder写入一个文件.

private static void write(StringBuilder sb, Boolean append) throws Exception {
    File file = File.createTempFile("foo", ".txt");

    FileWriter writer = new FileWriter(file.getAbsoluteFile(), append);
    PrintWriter out = new PrintWriter(writer);
    try {
        out.print(sb);           
        out.flush();
        writer.flush();
    } finally {
        writer.close();
        out.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

我读了这个其他的例子,但它同样很慢:在文本文件Java中编写大量数据的最快方法

我也尝试过NIO api:

private static void write(StringBuilder sb, Boolean append)) throws Exception {
    FileChannel rwChannel = new FileOutputStream("textfile.txt", true).getChannel();
    ByteBuffer bb = ByteBuffer.wrap(sb.toString().getBytes("UTF-8"));
    rwChannel.write(bb);
    rwChannel.close();
}
Run Code Online (Sandbox Code Playgroud)

将大量数据写入/附加到文件中的最佳方法是哪种?

Hol*_*ger 6

你不需要PrintWriter这里.如果您有任何类型Writer(例如a FileWriter),您可以简单地调用append(sb)它.你不需要flush,close暗示潮红.

private static void write(StringBuilder sb, Boolean append) throws Exception {
  File file = File.createTempFile("foo", ".txt");

  try(FileWriter writer = new FileWriter(file.getAbsoluteFile(), append)) {
      writer.append(sb);
  }
}
Run Code Online (Sandbox Code Playgroud)

在我的系统上,我遇到了一个小的性能改进,Channel而不是OutputStream:

private static void write0a(StringBuilder sb, Boolean append) throws Exception {
  File file = File.createTempFile("foo", ".txt");

  try(Writer writer = Channels.newWriter(new FileOutputStream(
      file.getAbsoluteFile(), append).getChannel(), "UTF-8")) {
    writer.append(sb);
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,这些只是轻微的改进.我没有看到很多可能性,因为所有代码最终调用相同的例程.能够真正提高性能的是在调用期间保持Writer活着,而不是刷新每条记录.


use*_*877 5

如果您有大量数据,最好不要将它存储到StringBuilder,然后立即将其写入文件.

这是最好的方案:

1)在开始处理数据之前创建FileInputStream

FileOutputStream fos = new FileOutputStream("/path/of/your/file");
Run Code Online (Sandbox Code Playgroud)

2)从该文件创建和OutputStreamWriter

OutputStreamWriter w = new OutputStreamWriter(fos, "UTF-8");
Run Code Online (Sandbox Code Playgroud)

3)创建BufferedWriter(提高文件写入性能)

BufferedWriter bw = new BufferedWriter(w);
Run Code Online (Sandbox Code Playgroud)

4)将bw传递给过程函数,然后冲洗/关闭

bw.flush();
bw.close();
Run Code Online (Sandbox Code Playgroud)

StringBuilder和BufferedWriter的功能几乎相同,因此您不需要更改代码.这种情况的唯一不利之处在于,您的流程将涉及数据写入文件的所有时间,但如果您不在不同的线程中处理数据,则不是问题.

通过这种方式,数据的大小并不重要