[英]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)
。 而且你不需要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);
}
}
在我的系統上,我使用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.