簡體   English   中英

如何在Java中附加/寫入大量數據文件文本

[英]How to append/write huge data file text in Java

我有一個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();
    }
}

我讀了這個其他的例子,但它同樣很慢: 在文本文件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();
}

將大量數據寫入/附加到文件中的最佳方法是哪種?

這里不需要PrintWriter 如果您有任何類型的Writer (例如FileWriter ),您只需在其上調用append(sb) 而且你不需要flushclose意味着沖洗。

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);
  }
}

在我的系統上,我使用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);
  }
}

然而,這些只是輕微的改進。 我沒有看到很多可能性,因為所有代碼最終調用相同的例程。 能夠真正提高性能的是在調用期間保持Writer活着,而不是刷新每條記錄。

如果您有大量數據,最好不要將它存儲到StringBuilder,然后立即將其寫入文件。

這是最好的方案:

1)在開始處理數據之前創建FileInputStream

FileOutputStream fos = new FileOutputStream("/path/of/your/file");

2)從該文件創建和OutputStreamWriter

OutputStreamWriter w = new OutputStreamWriter(fos, "UTF-8");

3)創建BufferedWriter(提高文件寫入性能)

BufferedWriter bw = new BufferedWriter(w);

4)將bw傳遞給過程函數,然后沖洗/關閉

bw.flush();
bw.close();

StringBuilder和BufferedWriter的功能幾乎相同,因此您不需要更改代碼。 這種情況的唯一不利之處在於,您的流程將涉及數據寫入文件的所有時間,但如果您不在不同的線程中處理數據,則不是問題。

通過這種方式,數據的大小並不重要

您正在使用FileWriter(或第二個示例中的FileOutputStream)。 這些都沒有緩沖! 所以他們寫單個字符。 磁盤的字節數。

這意味着,您應該將FileWriter包裝在BufferedWriter(或BufferedOutputSystem中的FileOutputSystem)中。

private static void write(StringBuilder sb, Boolean append) throws Exception {
    File file = File.createTempFile("foo", ".txt");
    Writer writer = new BufferedWriter(new FileWriter(file.getAbsoluteFile(), append));
    PrintWriter out = new PrintWriter(writer);
    try {
        out.print(sb);           
        out.flush();
        writer.flush();
    } finally {
        writer.close();
        out.close();
    }
}

您正在打開文件,寫一行,然后關閉它。 這是開始和結束,花時間在這里。 找到一種方法來保持輸出文件打開。

您是否嘗試過Apache IO,性能是否仍然相同?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM