2016-07-13 6 views
-1

Ich schreibe einen Strom von Zeichen in eine Textdatei in einer Single-Byte-Codierung. Ich möchte in der Lage sein, nicht zutreffende Zeichen im Stream zu finden, um eine Fallback-Aktion auszuführen (was auf hoher Ebene ist und ungültige Zeichen nicht löscht oder ersetzt).Detect nicht-Zeichen im Stream

Ich verwende OutputStreamWriter jetzt, aber wie kann ich sicher sein, dass es auf Mapping-Fehler werfen wird?

private void convert(Iterable<String> lines, OutputStream os) throws CoreException, IOException { 
    String lineDelimiter = ResourcesUtils.getLineDelimiter(file.getProject()); 
    Charset charset = Charset.forName(file.getCharset()); 
    CharsetEncoder encoder = charset.newEncoder(); 
    encoder.onUnmappableCharacter(CodingErrorAction.REPORT); 
    try (OutputStreamWriter writer = new OutputStreamWriter(os, encoder)) { 
     Joiner.on(lineDelimiter).appendTo(writer, lines); 
    } 
} 

Dieser Code führt auf Probe ungültige Eingabe, aber es ist unklar, ob es so auf andere Implementierungen von Output oder Eingaben zu tun ist garantiert.

Was ist eine zuverlässige Möglichkeit, eine Ausnahme beim Konvertieren eines Streams mit nicht-kompatiblen Zeichen zu erhalten?

+0

Haben Sie es versucht? Was ist passiert, wenn Sie ungültige Daten eingegeben haben? –

+0

Es funktionierte gut mit mir - nicht mit ** Guava Joiner ** obwohl. Vielleicht ist das der Schuldige. –

Antwort

0

Ich habe versucht, OutputStreamWriter mit verschiedenen Konstruktoren zu konstruieren und getestet, ob es bei Schreibversuch ummappable Eingabe werfen wird.

Generisches Testfall aussah:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
Writer writer = createWriter(outputStream); 
writer.write("ホク"); 
writer.close(); 

Mit folgenden createWriter() Implementierungen:

  • new OutputStreamWriter(outputStream, "windows-1251") - nicht
  • wirft
  • new OutputStreamWriter(outputStream, Charset.forName("windows-1251")) - werfen nicht
  • konfiguriert Geber:

    CharsetEncoder encoder = Zeichensatz.fürName ("windows-1251"). NewEncoder(); encoder.onUnmappableCharacter (CodingErrorAction.IGNORE); neuer OutputStreamWriter (outputStream, encoder);

    wirft nicht

  • new OutputStreamWriter(outputStream, Charset.forName("windows-1251").newEncoder()) -

Dieses Verhalten ist ein bisschen überraschend und is not specified wirft. Außerdem Dokumentation sagt:

Diese Klasse immer malformed Surrogat-Elemente und nicht zuzuordnenden Zeichenfolge mit dem Standard-Substitutionssequenz des charset ersetzt. Die CharsetEncoder-Klasse sollte verwendet werden, wenn mehr Kontrolle über den Codierungsvorgang erforderlich ist.

Das widerspricht letzten Experiment Ergebnissen.

Getestet auf Java (TM) SE Runtime Environment (build 1.8.0_72-b15) (Linux)

Output im Allgemeinen nicht auf Mapping Ausfällen wirft nicht, aber manchmal tut es. Ich werde es immer noch verwenden, da die rohe CharsetEncoder-API nicht streamfähig ist, aber robustere Lösungen willkommen sind.