Come aggiungere un BOM UTF-8 in java
-
10-10-2019 - |
Domanda
Ho una stored procedure Java che recupera record dalla tabella utilizzando oggetto di risultati e crea un file CSV.
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;
Ma il file CSV generato non mostra il carattere tedesco corretto. database Oracle ha anche un valore NLS_CHARACTERSET di UTF8.
Si prega di suggerire.
Soluzione
Per scrivere una distinta base in UTF-8 è necessario PrintStream.print()
, non PrintStream.write()
.
Inoltre, se si vuole avere BOM nel file csv
, credo che è necessario stampare una distinta base dopo putNextEntry()
.
Altri suggerimenti
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(...), StandardCharsets.UTF_8));
out.write('\ufeff');
out.write(...);
Questo scrive giustamente 0xEF 0xBB 0xBF al file, che è la rappresentazione UTF-8 della distinta base.
Credo che out.write('\ufeff');
dovrebbe essere effettivamente out.print('\ufeff');
.
il javadoc , il metodo write(int)
realtà scrive un byte ... senza alcuna codifica dei caratteri. Così scrive il out.write('\ufeff');
0xff
di byte. Al contrario, il metodo print(char)
codifica il carattere di una o byte utilizzando la codifica del flusso, e quindi scrive tali byte.
nel caso in cui la gente sono usando PrintStream
s, è necessario fare un po 'diverso. Mentre un Writer
farà qualche magia per convertire un singolo byte in 3 byte, un PrintStream
richiede che tutti i 3 byte della BOM UTF-8 singolarmente:
// Print utf-8 BOM
PrintStream out = System.out;
out.write('\ufeef'); // emits 0xef
out.write('\ufebb'); // emits 0xbb
out.write('\ufebf'); // emits 0xbf
In alternativa, è possibile utilizzare i valori esadecimali per coloro che sono direttamente:
PrintStream out = System.out;
out.write(0xef); // emits 0xef
out.write(0xbb); // emits 0xbb
out.write(0xbf); // emits 0xbf
Nel mio caso funziona con il codice:
PrintWriter out = new PrintWriter(new File(filePath), "UTF-8");
out.write(csvContent);
out.flush();
out.close();