Ho bisogno di suggerimenti sul modo di rimuovere BOM da un file UTF-8 e di creare una copia del resto del file xml.Come rimuovere BOM da un file XML in Java
risposta
Avere uno strumento che si rompe a causa di una distinta base in un file UTF-8 è una cosa molto comune nella mia esperienza . Non so perché ci siano così tanti downvotes (ma poi mi dà la possibilità di provare a ottenere abbastanza voti per vincere un badge SO speciale;)
Più seriamente: un BOM UTF-8 in genere non rende questo ha molto senso ma è pienamente valido (anche se scoraggiato) dalle specifiche. Ora il problema è che molte persone non sono consapevoli del fatto che un BOM è valido in UTF-8 e quindi ha scritto strumenti/API non funzionanti che non elaborano correttamente questi file.
Ora è possibile che si verifichino due problemi diversi: è possibile elaborare il file da Java oppure è necessario utilizzare Java per creare/correggere a livello di codice gli altri strumenti necessari.
Ho avuto il caso in un concerto di consulenza in cui l'helpdesk continuava a ricevere messaggi da utenti che avevano problemi con un editor di testo che avrebbe rovinato file UTF-8 perfettamente validi prodotti da Java. Quindi ho dovuto aggirare quel problema assicurandomi di rimuovere il BOM da ogni singolo file UTF-8 con cui ci stavamo confrontando.
Se si desidera eliminare un DB da un file, è possibile creare un nuovo file e saltare i primi tre byte. Per esempio:
... $ file /tmp/src.txt
/tmp/src.txt: UTF-8 Unicode (with BOM) English text
... $ ls -l /tmp/src.txt
-rw-rw-r-- 1 tact tact 1733 2012-03-16 14:29 /tmp/src.txt
... $ hexdump -C /tmp/src.txt | head -n 1
00000000 ef bb bf 50 6f 6b 65 ...
Come si può vedere, il file inizia con "ef bb bf", questo è il (pienamente valida) UTF-8 BOM.
Ecco un metodo che prende un file e fa una copia di esso saltando i primi tre byte:
public static void workAroundbrokenToolsAndAPIs(File sourceFile, File destFile) throws IOException {
if(!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
source.position(3);
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size() - 3);
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}
Si noti che si tratta di "raw": si dovrebbe menzionare vuole prima assicurarsi di avere un BOM prima di chiamare questo o "Bad Thinks May Happen" [TM].
Potete guardare il file in seguito:
... $ file /tmp/dst.txt
/tmp/dst.txt: UTF-8 Unicode English text
... $ ls -l /tmp/dst.txt
-rw-rw-r-- 1 tact tact 1730 2012-03-16 14:41 /tmp/dst.txt
... $ hexdump -C /tmp/dst.txt
00000000 50 6f 6b 65 ...
E il BOM è andato ...
Ora, se si vuole semplicemente rimuovere in modo trasparente la distinta per una vostra API Java rotto, allora si potrebbe utilizzare il PushbackInputStream descritto qui: why org.apache.xerces.parsers.SAXParser does not skip BOM in utf8 encoded xml?
private static InputStream checkForUtf8BOMAndDiscardIfAny(InputStream inputStream) throws IOException {
PushbackInputStream pushbackInputStream = new PushbackInputStream(new BufferedInputStream(inputStream), 3);
byte[] bom = new byte[3];
if (pushbackInputStream.read(bom) != -1) {
if (!(bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF)) {
pushbackInputStream.unread(bom);
}
}
return pushbackInputStream; }
Nota che questo funziona, ma deve defin itely NON risolvere il problema più grave in cui è possibile avere altri strumenti nella catena di lavoro che non funzionano correttamente con i file UTF-8 con una distinta componenti.
Ed ecco un link ad una domanda con una risposta più completa, che copre altre codifiche così:
voti non sono un giudizio sul * soggetto * di una domanda, sono un giudizio sulla * qualità * di una domanda. Guarda i tooltip per i pulsanti di voto. – skaffman
@skaffman: OK ma invece di downvoting ho chiesto se OP stava usando un file UTF-8 (che sospettavo per quel problema è fin troppo comune) e poi l'ho aggiunto alla domanda (e modificato i tag). Non so cos'altro si può dire: * "Come rimuovere una BOM da un file?" * È piuttosto auto-esplicativo. Ho aggiunto "UTF-8". Certamente sarebbe stato più facile per me fare semplicemente un downvote;) – TacticalCoder
@TacticalCoder ringrazia molto per i tuoi suggerimenti .. Sono sicuro che questo avrebbe risolto il problema che avevo. – hari
i downvotes non sono a causa di un duplicato, che stanno perché questa domanda è troppo ampia in natura - StackOverflow serve per aiutare con problemi di programmazione specifici e localizzati. Possiamo aiutarti a eseguire il debug di un programma, non ne scriveremo uno per te. –
Sto aspettando che questo arrivi a -5 prima di rispondere;) – TacticalCoder
@hari: qual è la codifica del tuo file? UTF-8? – TacticalCoder