2010-09-27 11 views
16

Il file in questione non è sotto il mio controllo. La maggior parte delle sequenze di byte è UTF-8 valida, non è ISO-8859-1 (o un'altra codifica). Voglio fare del mio meglio estrarre quante più informazioni possibili.Come rilevare sequenze di byte UTF-8 illegali per sostituirle in java inputstream?

Il file contiene alcune sequenze di byte illegali, quelle devono essere sostituite con il carattere di sostituzione.

Non è un compito facile, pensa che sia necessaria una certa conoscenza della macchina a stati UTF-8.

Oracle ha un involucro che fa quello che mi serve:
UTF8ValidationFilter javadoc

C'è qualcosa di simile a disposizione (in commercio o come software libero)?

Grazie
-stephan

Soluzione:

final BufferedInputStream in = new BufferedInputStream(istream); 
final CharsetDecoder charsetDecoder = StandardCharsets.UTF_8.newDecoder(); 
charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE); 
charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE); 
final Reader inputReader = new InputStreamReader(in, charsetDecoder); 
+10

Odio questo. i produttori di contenuti dovrebbero produrre contenuti validi, non chiedere ai consumatori di indovinare e correggere. Ciò ha causato così tanti problemi nel nostro settore. – irreputable

risposta

12

java.nio.charset.CharsetDecoder fa quello che ti serve. Questa classe fornisce la decodifica del set di caratteri con azioni definibili dall'utente su diversi tipi di errori (vedere onMalformedInput() e onUnmappableCharacter()).

CharsetDecoder scrive a un OutputStream, che è possibile tubo in un InputStream utilizzando java.io.PipedOutputStream, creando di fatto un filtrato InputStream.

+0

È stato molto utile, grazie. – user85155

+0

@Henning - cosa succede se voglio sapere su quale linea ci sono cattivi personaggi? – Dejell

+1

@Dejel è possibile dividere l'input in linee e provare a rilevare gli errori riga per riga. –

0

Un modo sarebbe quello di leggere i primi pochi byte per verificare il segno di ordine dei byte (se esiste). Ulteriori informazioni su BOM: http://en.wikipedia.org/wiki/Byte_order_mark Nell'URL specificato, troverete una tabella dei byte BOM. Tuttavia, un problema è che UTF-8 non richiede l'uso di BOM nella sua intestazione. C'è un altro modo per risolvere il problema è il riconoscimento di pattern (leggi qualche byte-8 bit ogni volta). Ad ogni modo, questa è la soluzione complicata ..

+0

Il problema non era una distinta base, era già stata rimossa. Esiste un BOMStripperInputStream mobile, che aiuta qui: http://code.google.com/p/train-graph/source/browse/trunk/src/org/paradise/etrc/data/BOMStripperInputStream.java?r=31 – user85155

0

Il comportamento che si desidera è già il valore predefinito per InputStreamReader. Quindi non c'è bisogno di specificarlo da solo. Questo è sufficiente:

final BufferedInputStream in = new BufferedInputStream(istream); 
final Reader inputReader = new InputStreamReader(in, StandardCharsets.UTF_8); 
Problemi correlati