BinaryStream als File speichern!

Hallo!

Ich hole ein als Blob gespeichertes, serialisiertes Objekt aus Oracle und will es als File auf meine Festplatte speichern. Das klappt auch schon ganz gut, aber…

 String fileName="PersonObjectDB.ser";
 Statement stmt = null;
 ResultSet rset = null;

 stmt = conn.createStatement();
 rset = stmt.executeQuery("SELECT \* FROM blobtest27");

 if (rset.next())
 { 
 FileOutputStream file = new FileOutputStream(fileName);
 InputStream fin = rset.getBinaryStream(1); 

Alternative 1: Falsche Abbruchbedingung, denn er beendet das
Schreiben der Datei, wenn er einen Character mit dem Wert 01
erhält! Der kommt leider des Öfteren vor, da das Objekt ja binär
gespeichert ist.
In der Datei habe ich jedoch zumindest den Anfang des
serialisierten Objekts, den ich in die DB geschrieben habe.

 int c;
 while ((c = fin.read()) != 1)
 file.write(c); 

Alternative 2: Jetzt bekomme ich fast die gesamte Datei, aber
der letzte Hex-Wert fehlt natürlich. Wenn ich >0 oder !=0
schreibe, wird eine immer größer werdende Datei (mit gleichen
„Müllzeichen“) erzeugt, solange bis ich javaw.exe abschieße!

 int c = fin.read();
 while (fin.available() != 1) 
 file.write(c);

 file.close();
 }

Wer hat eine Idee, wie es funktionieren könnte? Vielen Dank schon mal für Eure Tips!

Grüße, Tanja

int c;
while ((c = fin.read()) != 1)
file.write©;

Folgendes aus der JDK-Doku:

Returns:
the next byte of data, or -1 if the end of the stream is reached.

Du musst also auf != -1 testen.

int c = fin.read();
while (fin.available() != 1)
file.write©;

file.close();
}

Auch aus der Doku:

Returns:
the number of bytes that can be read from this input stream without blocking.

Ich denke nicht, dass du überhaupt diese Methode benutzen solltest. 1. hat sie einen anderen Sinn, 2. ist das im Vergleich zum read alleine ein zusätzlicher, unnötiger Methodenaufruf und wenn du es schon machst, dann musst du auf >0 testen.
Wobei ich nicht weiss, ob das wirklich funktionier. Wie gesagt, die Methode hat einen anderen Sinn. Ob das so funktioniert hängt davon ab, ob der Input-Buffer, wenn er leer ist automatisch aufgefüllt wird oder ob der erst beim nächsten read aufgefüllt wird - dann nämlich ist es ein blocking-read und die Methode liefert 0 zurück, obwohl der Stream noch gar nicht am Ende ist.

Noch ein Zusatz:
verwende zum schreiben von Dateien lieber einen Buffer! Wenn du das Byte für Byte machst wird es gähnend langsam!

int c;
byte[] buffer=new byte[32000];
while ((c = fin.read(buffer)) != -1)
file.write(buffer,0,c);

Gruß
Benky

Hallo Andreas!

int c;
while ((c = fin.read()) != 1)
file.write©;

Folgendes aus der JDK-Doku:

Returns:
the next byte of data, or -1 if the end of the stream is
reached.

Danke Andreas, ich werde in Zukunft immer erst die Doku lesen, bevor ich weitere blöde Fragen stelle! *peinlich* Irgendwie hatte ich gestern gar nicht daran gedacht oder ich war zu müde.

int c = fin.read();
while (fin.available() != 1)
file.write©;

file.close();
}

Auch aus der Doku:

Returns:
the number of bytes that can be read from this input stream
without blocking.

Ich denke nicht, dass du überhaupt diese Methode benutzen
solltest. 1. hat sie einen anderen Sinn, 2. ist das im
Vergleich zum read alleine ein zusätzlicher, unnötiger
Methodenaufruf und wenn du es schon machst, dann musst du auf
>0 testen.

Das hatte ich versucht, aber dann bekam ich eine immer größer werdende Datei. OK, also dann lieber Alternative 1.

funktioniert hängt davon ab, ob der Input-Buffer, wenn er leer
ist automatisch aufgefüllt wird oder ob der erst beim nächsten
read aufgefüllt wird - dann nämlich ist es ein blocking-read
und die Methode liefert 0 zurück, obwohl der Stream noch gar
nicht am Ende ist.

Aha.

verwende zum schreiben von Dateien lieber einen Buffer! Wenn
du das Byte für Byte machst wird es gähnend langsam!

Nochmal Danke, wird gemacht.

Grüße, Tanja

int c = fin.read();
while (fin.available() != 1)
file.write©;

file.close();
}

Das hatte ich versucht, aber dann bekam ich eine immer größer
werdende Datei. OK, also dann lieber Alternative 1.

Habs vergessen zu erwähnen:
Das Problem ist, dass du das read nicht in der Schleife machst. Du liest also einmal ein Zeichen und schreibst das bis Sankt Nimmerlein in die Datei. (Äh solltest dir unbedingt ne größere Platte dafür anschaffen ;o)

Gruß
Benky