FileOutPutStream in FileOutputStream

Status
Nicht offen für weitere Antworten.

Clip

Bekanntes Mitglied
Hallo!

ich habe das Problem, dass ich von einer Klasse ein FileOutPutStream Objekte bekomme und dieses speichern möchte.
Dabei soll ein File an einem definierten Ort erstellt werden.
Mein Problem dabei ist, das FileOutputStream nur write() Methoden besitzt.
Daher meine Frage:
Wie kann ich am einfachsten eine Kopie eines FileOutputStream Objektes an einem definirbaren Ort erstellen?

Danke!
 

Bleiglanz

Gesperrter Benutzer
du kannst einen Stream nicht "speichern"!

wenn du den FileOutputStream bekommst, dann gehört ja da iA schon eine geöffnete Datei dazu :)
 

Clip

Bekanntes Mitglied
Nun ja, ich hatte sowas befürchtet.
Ich muss aber auch nicht um jeden Preis einen anderen Stream zum Speichern verwenden.
Wie kann ich den den Inhallt des FileOutputStream Objektes in ein File speichern?
 

Bleiglanz

Gesperrter Benutzer
ein OutputStream hat keinen Inhalt!

das ist ein schwarzes Loch, in das man Daten reinschreiben kann!!!
 

Clip

Bekanntes Mitglied
???:L
hm, ok das klingt (leider) logisch.
Aber wie kann ich dann an Daten herankommen welche in ein OutputStream geschrieben werden dessen Pointer ich habe. Gibt es da eine Möglichkeit?
 

Mag1c

Top Contributor
Hi,

das geht nur, wenn du demjenigen, der in den OutputStream schreibt, einen anderen OutputStream
unterschieben kannst. Dann könntest du den Stream anzapfen.

Gruß
Mag1c
 

Bleiglanz

Gesperrter Benutzer
Aber wie kann ich dann an Daten herankommen welche in ein OutputStream geschrieben werden dessen Pointer ich habe. Gibt es da eine Möglichkeit?
komische Frage

normalerweise sollte immer nur einer in den Stream schreiben, nämlich der, der die Referenz darauf hat

und die hast du ja selber?
 

Clip

Bekanntes Mitglied
Ich habe eine Klasse welche von der Klasse "org.apache.cocoon.serialization.FOPSerializer" abgeleitet ist. Spich einen eigenen Cocoon serializer (http://www.planetcocoon.com/).
Code:
package swl.test.cocoon.serialization;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import org.apache.cocoon.serialization.FOPSerializer;
import org.xml.sax.SAXException;

public class Swlfo2pdf extends FOPSerializer {
	

	public void endDocument(){
		try {
			super.endDocument();
			FileOutputStream myout = new FileOutputStream("c:/temp/myout.pdf");
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Auf den OutputStream kann mit "this.output" zugegriffen werden.

Grund dafür ist, dass ich den von Cocoon erzeugten Output (der zum Client gesendet wird) auf der Festplatte des Servers speichern will. und zwar paralell zur Ausgabe auf einem Client.
Der Swlfo2pdf Serializr funktioniert üeberigens klasse, aktuell bekomme ich auf den Client das PDF und auf dem Server unter c:/temp/ ein leeres Dokument myout.pdf :)
Toller wäre natürlich, wenn das Dokument identisch mit dem wäre welches as den Client geschickt wird.
 

Bleiglanz

Gesperrter Benutzer
schau dir mal den FOPSerializer an, wenn der gutmütig ist dann geht vielleicht folgendes

in Startdokument machst du

webout = this.output
this.output = new ByteArrayOutputStream
super.startDocument // ? oder vorher schon?

(musst natürlich hoffen, dass du dem Parent den stream so unterjubeln kannst)

in endDocument

super.endDocument
jetzt ist alles im Bytearray
dann alles auf Platte
und nochmal alles nach webout
 

Clip

Bekanntes Mitglied
dann alles auf Platte

Ja, aber wie kann ich denn sagen wohin damit?
Die einzige Möglichkeit die ich gefunden habe einen FileOutputStream zu sagen wo er hinzeigen soll, ist im c'tor. Und wenn ich den ausfühe ändere ich ja den Pointer (bzw. erstelle ein neues Objekt), und verliere damit die Referenz zum alten....

Sorry, bin C++ Umsteiger und kenne die Java API noch nicht so gut....
 

Mag1c

Top Contributor
Hi,

na das ist dann alles im ByteArrayOutputStream gespeichert, im RAM sozusagen. Du kannst natürlich alternativ
mal einen FileOutputStream probieren:

this.output = new FileOutputStream("c:/temp/myout.pdf");

Gruß
Mag1c
 

Clip

Bekanntes Mitglied
womit wir wieder beim c'tor wären :(
gibt es keine Möglichkeit dem FileOutputStream nachträglich zu sagen wohin er zeigen soll?
 

Clip

Bekanntes Mitglied
c'tor = Konstruktor

Ich habe ja schon ein FileoutputStream.

Code:
FileOutputStream myout = new FileOutputStream("c:/temp/myout.pdf");

natürlich ist das von Bleiglanz vorgeschlagene Verfahren klüger.
Nur, angenommen ich habe jetzt einen OutputStream webout. Wie kriege ich diesen in ein File meiner Wahl?
 

Mag1c

Top Contributor
Ja genau, den nimmst du mal. Die Frage ist doch im Moment, ob du den OutputStream überhaupt durch einen anderen austauschen kannst. D.h. setze dort deinen eigenen OutputStream und schau nach, ob dann in dem betreffenden
File ein .pdf geschrieben wurde.

Falls das klappt, mußt du eine eigene OutputStream-Klasse schreiben, die Daten entegen nimmt und über einen anderen OutputStream wieder rausschreibt und parallel dazu in eine Datei (ähnl. dem Unix-Befehl tee, falls du den kennst).

Gruß
Mag1c
 

Clip

Bekanntes Mitglied
die Daten entegen nimmt und über einen anderen OutputStream wieder rausschreibt

Das ist genau der Kern des Problems. Wie krege ich den OutputStream in den FileOutputStream?

Ein OutputStream hat nur write Methoden um sich zu füllen, aber nichts zum schreiben.

Oder übersehe ich das was elementares?
 

Mag1c

Top Contributor
also mal ganz grob und unscharf :wink:

Code:
public class MyOutputStream extends OutputStream {
    public MyOutputStream ( OutputStream out ) {
        origOut = out;
        tmpfileOut = new FileOutputStream("c:/temp/myout.pdf");
    }

    public void write ( int b ) throws IOException {
        try {
            tmpfileOut.write(b);
        }
        catch ( IOException ex ) {
        }
        origOut.write(b);
    }

    public void close () throws IOException {
        try {
            tmpfileOut.close();
        }
        catch ( IOException ex ) {
        }
        origOut.close();
    }

    private OutputStream origOut;
    private OutputStream tmpfileOut;
}
 

Clip

Bekanntes Mitglied
Danke für Deine Mühe!

Nur leider kann ich keine Stelle entdecken, ab der "tmpfileOut" ein Inhalt zugewiesen würde. :(
D.h. ich erhielte weiterhin nur ein leeres File.

wenn ich
Code:
			FileOutputStream out = new FileOutputStream("c:/temp/out.pdf");
			FileInputStream in = new FileInputStream("c:/temp/in.pdf");

			copy(in, out);
			
			out = new FileOutputStream("c:/temp/myout2.pdf");

Code:
	public static void copy(FileInputStream fis, FileOutputStream fos){
		
		try{
			byte[] buffer = new byte[0xffff];
			int nbytes;
			
			while ((nbytes = fis.read(buffer)) != -1){
				fos.write(buffer, 0, nbytes);				
			}
		}
		catch (IOException e){
			System.err.println(e);
		}
		finally{
			if (fis != null)
				try{
					fis.close();
				}
				catch(IOException e){
					System.err.println(e);		
				}
			if (fos != null){
				try{
					fos.close();
				}
				catch(IOException e){
					System.err.println(e);		
				}				
			}			
		}			
	}
ausführe, erhalte ich zwar ein File out.pdf, das bis auf den Namen indentisch zu in.pdf ist. Ferner ein leeres myout.pdf

Wie kriege ich den Inhalt von dem File auf welches FileOutputStream out zeigt OHNE Zurhilfenahme von FileInputStream in in ein anderes File kopiert? UNd zwar ohne zu wissen wie out heißt....
 

Mag1c

Top Contributor
Hi,

siehe Zeile 9: tmpfileOut.write(b);

habs mal ausprobiert. Hier also nun ein funktionierendes Bsp.:

Code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class JTee {

	public static void main (String[] args) {
		try  {
			copy("/home/micha/katalog2005.pdf", "/home/micha/kopie.pdf");
		}
		catch ( IOException ex ) {
			ex.printStackTrace();
		}

	}

	public static void copy (String fin, String fout) throws IOException {
		FileInputStream fis = new FileInputStream(fin);
		MyOutputStream fos = new MyOutputStream(new FileOutputStream(fout), "/home/micha/ktemp.pdf");
		try {
			byte[] buffer = new byte[0xffff];
			int nbytes;

			while ((nbytes = fis.read(buffer)) != -1) {
				fos.write(buffer, 0, nbytes);
			}
		}
		finally {
			fis.close();
			fos.close();
		}
	}

	public static class MyOutputStream extends OutputStream {
		public MyOutputStream(OutputStream out, String tmp) {
			origOut = out;
			try {
				tmpfileOut = new FileOutputStream(tmp);
			}
			catch (IOException ex) {}
		}

		public void write (int b) throws IOException {
			try {
				if ( tmpfileOut != null ) 
					tmpfileOut.write(b);
			}
			catch (IOException ex) {}
			origOut.write(b);
		}

		public void close () throws IOException {
			try {
				tmpfileOut.close();
			}
			catch (IOException ex) {}
			origOut.close();
		}

		private OutputStream origOut;
		private OutputStream tmpfileOut;
	}
}

Achja, hier noch das Ergebnis :)

Code:
> ll /home/micha/k*.pdf
-rw-r--r--  1 micha users 3240379 2005-04-24 22:08 /home/micha/katalog2005.pdf
-rw-r--r--  1 micha users 3240379 2005-09-14 21:52 /home/micha/kopie.pdf
-rw-r--r--  1 micha users 3240379 2005-09-14 21:52 /home/micha/ktemp.pdf

Gruß
Mag1c
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben