Selbst geschriebener InputStreamReader über einen beliebigen InputStream

megalomaniac

Mitglied
Hallo zusammen,

ich betreibe ein Programm, das XML-Dateien über eine beliebige Schnittstelle (z.B. von Platte oder über einen http-Request) in Form eines InputStreams einliest und weiterverarbeitet. Da bestimmte in diesen Dateien enthaltene Zeichen transformiert werden sollen, habe ich einen XmlInputStreamReader (abgeleitet von InputStreamReader) geschrieben, der diese Transformationsregeln implementiert. Soweit alles okay.

Leider liegen nicht alle XML-Dateien im gleichen Encoding vor. Die Dateien können UTF-8 oder ANSI (ISO-8859-1) kodiert sein. Herausbekommen kann ich das Encoding prinzipiell nur anhand des XML-Headers am Anfang des eingelesenen Datenstroms. Das Encoding muss ich der Superklasse meines XmlInputStreamReaders mitliefern, damit mir der Parser zum späteren Zeitpunkt die Daten des XMLs vernünftig zurückliefert.

Und genau hier liegt mein Problem! Ich muss beim Instanziieren meines XmlInputStreamReaders dem Konstruktor das Encoding mitliefern, zu einem Zeitpunkt, an dem ich noch gar nicht angefangen habe, den Inhalt meines InputStreams auszulesen. Hier mal der passende Quellcode dazu:

Java:
public class XmlInputStreamReader extends InputStreamReader {
	
	(...)
	
    public XmlInputStreamReader(InputStream in, String charsetName) throws UnsupportedEncodingException
    {
        super(in, charsetName);
    }
	
	(...)
}

Ein Henne-Ei-Problem! Ich kann meinen Reader nicht instanziieren, weil ich auf den Inhalt des Streams zugreifen muss, um die notwendigen Encoding-Informationen zu bekommen. Ein nachträgliches Setzen des Encodings ist in der Superklasse InputStreamReader offenbar nicht vorgesehen.

Erschwerend kommt hinzu, dass das Programm relativ performanzkritisch ist. Es werden viele Tausend XML-Dateien (zum Teil mit Volumina > 200 MB) sequentiell verarbeitet. Ich schätze also, dass das naheliegende Vorgehen

1. Stream "anlesen"
2. Encoding ermitteln
3. Stream wegwerfen und neu von der Schnittstelle beziehen
4. XmlInputStreamReader mit jeweiligem Encoding instanziieren

aus Gründen der Performanzerhaltung in meinem Fall nicht zielführend ist.

Lange Rede kurzer Sinn: Fällt jemandem zu meinem Problem eine elegante Lösung ein?
 
S

SlaterB

Gast
> aus Gründen der Performanzerhaltung in meinem Fall nicht zielführend ist.

warum schätzt du das, irgendwas schon dazu getestet? geht es dir nur um abstrakte Punkte wie 'Erzeugen des Stream-Objekte
oder hast du praktische Hinweise wie 'jedes Lesen aus der Schnittstelle kostet sowieso erstmal 3 sec'?

was Java-intern zum Anfordern eines Stream/ Erzeugen eines Objektes an Arbeit anfällt besser selber nicht zu beurteilen versuchen falls nicht unumgänglich

-----

ein Vorschlag: den Stream aus der Schnittstelle cachen, bei kleinen Dateien unter 1 MB vielleicht komplett in ein byte[] einlesen,
darauf dann einen Stream der die ersten bytes liest (ByteArrayInputStream) und mit bekanntem Encoding einen neuen Stream auf das immer noch komplett vorliegende byte[], das wird nicht 'verbraucht',
oder das Encoding direkt aus den bytes feststellen,

inwiefern das Performance-Probleme macht (z.B. zusätzliche 1 MB Arbeitsspeicher), kann man belieblig entscheinden,
komplizierter aber performanter wäre wahrscheinlich doch ein ein eigener Stream, der nur die ersten x bytes cacht
(herausfinden wieviel zur Encoding-Bestimmung benötigt werden),
dieser ersten x bytes eben zur Encoding-Bestimmung einsetzen und danach normal weitergeben, die restlichen bytes direkt durchreichen bzw. aus einen dann mit Encoding initialisieren wirklichen InputStreamReader als Klassenattribut,

(ich sehe gerade Reader statt Stream, überall ruhig byte durch char ersetzen)

auf Methoden der Basisklasse InputStreamReader kannst du dich dann natürlich nicht verlassen, du musst alle wichtigen Methoden überschreiben und direkt aus dem Parameter in lesen,
manche Methoden muss man nicht überschreiben, z.B.

Java:
   public int read(char cbuf[]) throws IOException {
	return read(cbuf, 0, cbuf.length);
    }
kann so bleiben, wenn
> public int read(char cbuf[], int off, int len)
überschrieben ist usw.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Hibernate Envers - Aufruf der Methode zum Speichern selbst ausführen oder managen? Allgemeine Java-Themen 0
P JavaFX Anwendung beendet sich selbst nur als Jar Allgemeine Java-Themen 40
L Excel Datei löscht sich selbst im Programm - Java Allgemeine Java-Themen 3
G Beendet sich der Thread selbst?! Allgemeine Java-Themen 3
W IDEA IntelliJ Build-Management-Tool selbst programmieren Allgemeine Java-Themen 2
Tausendsassa Threads Einen Thread sich selbst schließen lassen Allgemeine Java-Themen 17
S Mit Generics Klasse erstellen die selbst T erweitert..? Allgemeine Java-Themen 4
S Shape selbst rendern..? Allgemeine Java-Themen 5
N Automatisches einfügen einer selbst generierten ID in Klasse mit Annotation Allgemeine Java-Themen 8
M Programm startet sich selbst neu, alte Logfiles bleiben gesperrt Allgemeine Java-Themen 2
Z Klassen ArrayList selbst machen Allgemeine Java-Themen 5
R JRE Ablaufdatum seit 7u10 - Probleme bei selbst ausgelieferter JRE bekannt? Allgemeine Java-Themen 3
J kann eine .jar sich selbst verschieben? Allgemeine Java-Themen 6
C Eclipse Probleme bei selbst erstelltem Algorithmus Allgemeine Java-Themen 2
Q Zeit in GUI selbst aktualisieren Allgemeine Java-Themen 5
D PriorityQueue selbst implementieren Allgemeine Java-Themen 15
K Serialisierung komplett selbst machen Allgemeine Java-Themen 13
W Annotations selbst erstellen und auswerten Allgemeine Java-Themen 4
J Können Programme sich selbst erweitern? Allgemeine Java-Themen 6
J Objekt selbst ertellen möglich? Allgemeine Java-Themen 6
J Crawler selbst geschreiben: OutOfMemoryError Allgemeine Java-Themen 14
N JFrame Icon selbst erzeugen Allgemeine Java-Themen 2
PAX Applikation sich selbst neu starten lassen Allgemeine Java-Themen 27
P Eigene Klasse kopieren die auf sich selbst refferenziert Allgemeine Java-Themen 8
R synchronized "gegen sich selbst" Allgemeine Java-Themen 5
J BufferedWriter schreibt von selbst ein "" Allgemeine Java-Themen 12
H JButtons selbst gestallten Allgemeine Java-Themen 6
V Sich selbst kopieren (Jar- Datei) Allgemeine Java-Themen 3
ARadauer programm soll sich selbst ändern können Allgemeine Java-Themen 20
F Klasse soll sich selbst returnieren mit entsprechendem Typ. Allgemeine Java-Themen 15
V Avatar selbst programmieren Allgemeine Java-Themen 4
E externe Anwendung aufrufen und sich selbst beenden Allgemeine Java-Themen 8
F Kann Applet installierte JVM selbst auswählen? Allgemeine Java-Themen 4
R DropTarget auch für Applet selbst Allgemeine Java-Themen 2
M vererbung einer "selbst-instanzierungs-klasse" Allgemeine Java-Themen 16
J ID selbst vergeben Allgemeine Java-Themen 2
E Einer Methode sich selbst übergeben . ? Allgemeine Java-Themen 5
J Fenster mit paint Methode selbst zeichnen Allgemeine Java-Themen 3
C Vectoren befuellen sich von selbst Allgemeine Java-Themen 2
P Programm selbst starten lassen Allgemeine Java-Themen 2
B Installshield selbst gemacht Allgemeine Java-Themen 3
E Objekt serialisiert sich selbst Allgemeine Java-Themen 2
D 'InputStreamReader' & 'BufferedReader' führen zu "cannot find symbol"-Fehler Allgemeine Java-Themen 3
N InputStreamReader-> DataInputStream-> Socket.getInputS Allgemeine Java-Themen 25
J InputStreamReader friert ein Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben