27

Resultsetオブジェクトを使用してテーブルからレコードをフェッチし、CSVfileを作成するJavaストアドプロシージャがあります。

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データベースにもNLS_CHARACTERSETUTF8の値があります。

提案してください。

4

8 に答える 8

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

これにより、0xEF 0xBB 0xBFがファイルに正しく書き込まれます。これは、BOMのUTF-8表現です。

于 2011-11-14T11:18:48.947 に答える
16

人々sを使用している場合に備えPrintStreamて、少し異なる方法でそれを行う必要があります。aWriterは1バイトを3バイトに変換するために魔法をかけますが、aPrintStreamはUTF-8BOMの3バイトすべてを個別に必要とします。

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

または、それらの16進値を直接使用することもできます。

    PrintStream out = System.out;
    out.write(0xef); // emits 0xef
    out.write(0xbb); // emits 0xbb
    out.write(0xbf); // emits 0xbf
于 2016-03-30T14:29:54.940 に答える
11

PrintStream.print()UTF-8でBOMを作成するには、ではなく、が必要ですPrintStream.write()

また、csvファイルにBOMを含めたい場合は、の後にBOMを印刷する必要があると思いますputNextEntry()

于 2010-12-08T15:41:35.367 に答える
11

PrintStream#print

out.write('\ufeff');それは実際にout.print('\ufeff');は、メソッドを呼び出す必要があると思いますjava.io.PrintStream#print

javadocによると、このwrite(int)メソッドは実際には文字エンコードなしで1バイトを書き込みます。したがってout.write('\ufeff');、バイトを書き込みます0xff。対照的に、このprint(char)メソッドは、ストリームのエンコーディングを使用して文字を1バイトまたはバイトとしてエンコードし、それらのバイトを書き込みます。

Unicode 9仕様のセクション23.8に記載されているように、UTF-8のBOMはですEF BB BF。そのシーケンスは、でUTF-8エンコーディングを使用したときに得られるものです'\ufeff'。参照:UTF-8BOMバイトefbbbfを\ufeffに置き換えることができるのはなぜですか?

于 2010-12-08T15:42:06.907 に答える
5

これをCSV文字列の最初に追加します

String CSV = "";
byte[] BOM = {(byte) 0xEF,(byte) 0xBB,(byte) 0xBF};
CSV = new String(BOM) + CSV;

この仕事は私のために。

于 2020-07-15T15:48:45.220 に答える
0

私の場合、それはコードで動作します:

PrintWriter out = new PrintWriter(new File(filePath), "UTF-8");
out.write(csvContent);
out.flush();
out.close();
于 2013-12-19T09:01:34.900 に答える
0

ここに、任意のファイルにBOMヘッダーを追加する簡単な方法があります。

private static void appendBOM(File file) throws Exception {
    File bomFile = new File(file + ".bom");
    try (FileOutputStream output = new FileOutputStream(bomFile, true)) {
        byte[] bytes = FileUtils.readFileToByteArray(file);
        output.write('\ufeef'); // emits 0xef
        output.write('\ufebb'); // emits 0xbb
        output.write('\ufebf'); // emits 0xbf
        output.write(bytes);
        output.flush();
    }
    
    file.delete();
    bomFile.renameTo(file);
}
于 2020-12-22T15:24:21.357 に答える
0

同じファイルを変更したい場合(新しいファイルなしで、問題があったので古いファイルを削除します)

private void addBOM(File fileInput) throws IOException {
    try (RandomAccessFile file = new RandomAccessFile(fileInput, "rws")) {
        byte[] text = new byte[(int) file.length()];
        file.readFully(text);
        file.seek(0);
        byte[] bom = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
        file.write(bom);
        file.write(text);
    }
}
于 2021-06-24T14:03:00.703 に答える