2010-12-08 347 views
14

我有一個Java存儲過程,它使用Resultset對象從表中提取記錄並創建一個csv文件。如何在java中添加UTF-8 BOM

BLOB retBLOB = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION); 
retBLOB.open(BLOB.MODE_READWRITE); 
OutputStream bOut = retBLOB.setBinaryStream(0L); 
ZipOutputStream zipOut = new ZipOutputStream(bOut); 
PrintStream out = new PrintStream(zipOut,false,"UTF-8"); 
out.write('\ufeff'); 
out.flush(); 
zipOut.putNextEntry(new ZipEntry("filename.csv")); 
while (rs.next()){ 
    out.print("\"" + rs.getString(i) + "\""); 
    out.print(","); 
} 
out.flush(); 
zipOut.closeEntry(); 
zipOut.close(); 
retBLOB.close(); 
return retBLOB; 

但生成的csv文件沒有顯示正確的德文字符。 Oracle數據庫還具有UTF8的NLS_CHARACTERSET值。

請建議。

+1

如果您以前沒有遇到過這種情況,請注意,Unicode標準不要求或推薦使用帶有UTF-8的BOM。這也不是非法的,但不應該不加選擇地使用。有關詳細信息,請參閱[此處](http://unicode.org/faq/utf_bom.html#BOM),其中包含有關何時何地使用它的一些準則。如果您嘗試在Windows中查看csv文件,這可能是對BOM的有效使用。 – 2010-12-08 15:16:25

+0

是的,我們正試圖在Windows中查看csv,但生成的csv仍然顯示德語字符的亂碼。這是設置BOM的正確方法嗎? – Fadd 2010-12-08 15:20:43

+0

是的,沒錯。 Unicode標準建議使用UTF-8使用所謂的BOM(它不是真正的)來反對**。 – tchrist 2010-12-08 17:05:35

回答

7

要以UTF-8編寫BOM,您需要PrintStream.print()而不是PrintStream.write()

另外如果你想有你的csv文件中的BOM,我猜你需要在putNextEntry()之後打印BOM。

7

我認爲out.write('\ufeff');實際上應該是out.print('\ufeff');

根據the javadocwrite(int)方法實際上寫入一個字節...沒有任何字符編碼。所以out.write('\ufeff');寫入字節0xff。相反,print(char)方法使用流的編碼將字符編碼爲一個或多個字節,然後寫入這些字節。

49
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(...), StandardCharsets.UTF_8)); 
out.write('\ufeff'); 
out.write(...); 

這正確地將0xEF 0xBB 0xBF寫出到文件,這是BOM的UTF-8表示形式。

0

在我的情況下,它的工作原理與代碼:

PrintWriter out = new PrintWriter(new File(filePath), "UTF-8"); 
out.write(csvContent); 
out.flush(); 
out.close(); 
3

只需使用PrintStream案人,你需要以不同的方式做到這一點。雖然Writer會做一些神奇的單字節轉換成3個字節,一個PrintStream要求所有3個字節的UTF-8 BOM的獨立:

// Print utf-8 BOM 
    PrintStream out = System.out; 
    out.write('\ufeef'); // emits 0xef 
    out.write('\ufebb'); // emits 0xbb 
    out.write('\ufebf'); // emits 0xbf 

或者,您可以用十六進制值對於那些直接:

PrintStream out = System.out; 
    out.write(0xef); // emits 0xef 
    out.write(0xbb); // emits 0xbb 
    out.write(0xbf); // emits 0xbf