Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Input/OutputInputStream (JSch) in OutputStream (Blob) überführen
Guten Morgen,
ich versuche derzeit eine Datei, die ich mittels SFTP (via JSch) downloade in einen Blob zu überführen. Die Datei zu erhalten funktioniert auch und ich kann sauber ein InputStream darauf setzten. Um einen Blob zu schreiben kann man diesem einem Outputstream anhängen, auch das funktioniert
Java:
InputStream in = getChannel().get(dateiname);
OutputStream out = b.setBinaryStream(0);
Soweit so gut, aber mein Programm schmiert immer ab, wenn ich nun den Übertrag machen möchte bleibt das ganze hängen und ich muss es manuell abschießen, damit ich weitearbeiten kann.
Hier der Versuch den Input in den Output zu überführen.
Java:
byte[] data = new byte[1024];
int i = 0;
try {
while ((i = in.read(data)) != -1) {
out.write(data, 0, i);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Hat jemand eine Idee was ich falsch mache bzw. wie ich den Übertrag gefixt kriege? Eine Fehlermeldung erhalte ich nicht.
Der InputStream wird erhlaten und die Zeichen korrekt ausgelesen (was ich mittels Sysout mir angucke). Jedoch bleibt der BLOB (bzw CLOB, hab beides ausprobiert) unverändert. Der hat vor dem Betreten der Schleife eine Länge von 86 byte (was auch immer die Zeichen die da drin stehen sein sollen) und verändert sich nicht - heißt es wird irgendwie keine Data angehangen und die Länge bleibt immer gleich. Dies zeigt sich zumindest beim Debuggen in Eclipse, wenn ich mir den BLOB angucke.
Jemand da eine Idee warum der out.write() nicht beim Blob "ankommt"?
Das ist unsinnig, du machst für jedes byte das du schreibst einen neuen Stream auf.
Java:
int nextByte;
OutputStream out = b.setOutputStream(0);
while ( ( nextByte= in.read() ) != -1 )
{
out.write( nextByte );
}
out.flush();
Flush macht erst am Ende Sinn und der Stream heisst ja nicht Stream weil er immer wieder von vorner zu schreiben beginnt, sondern weils ein Strom von Daten ist, der von selber weiterschreibt.
Meines Wissens nach sicher Flush den Buffer. Und da ich es mit einer extrem großen Datei zu tun habe will ich nicht riskieren, dass mir der Buffer um die Ohren fliegt?!?
Flush schreibt den Buffer auf den Stream. Wenn du so wie in deinem Beispiel nach jedem Byte den Stream flusht, führst du den Buffer ad absurdum und es bremst gewaltig aus.
Ich bin mir nicht mal sicher ob dir in Java der Buffer überhaupt noch um die Ohren fliegen kann, ich schätze aber es wäre ein Zähler in deiner Schleife, der eben dann alle 1024 Bytes den Stream flusht, besser als nach jedem Byte zu flushen.
selbstverständlich wird ein Buffer automatisch geflusht wenn nötig,
solche Buffer sind idealerweise unsichtbar in der Stream-Kette eingebaut:
> OutputStream x = new XYStream(new BufferedOutputStream(new FileOutputStream(..)));
so dass gar keine Möglichkeit bestände, da flush() aufzurufen, das will man nicht
Du benutzt ja einen OutputStream. Ein kurzer blick in die API:
The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such bytes should immediately be written to their intended destination.
Beim OutputStream musst du den Stream schließen mit close() bevor da überhaupt etwas irgendwo "reingeschrieben" wird (anders als bei den BufferedStreams, bei denen das flush() durch das "leeren" des Buffers, das schreiben bewirkt.
Fazit: Du solltest einen BufferedOutputStream bzw. BufferedWriter nutzen oder einfach dein Stream am ende schließen mit close()
Beim BufferedWriter aber, jeden byte zu flushen ist böse ^^ Außerdem, wenn du mal in die Sourcen reinguckst, wirst du feststellen, dass der BufferedWriter intern überprüft ob die maximale (default, oder die von dir festgelegte) größe nicht erreicht/überschritten wurde, und wenn ja, dann führt er flush() automatisch aus. Da brauchst du es gar nicht aufzurufen. ggf. nur zur sicherheit vor dem close() obwohl das eigentlich auch überflüssig ist, da beim aufruf von close() auch intern noch flush() ausgeführt wird.
Es würde ja sonst kein Sinn machen, die maximale größe des Buffers einstellbar zu machen, wenn er nicht selbst flushen würde