# String in einen OutputStream schreiben - welche Klassen verwenden?



## DarthShader (16. Juli 2008)

Hallo,

ich komme immer wieder ins Schleudern, wenn es um diese ganzen verschiedenen IO Klassen geht, wie PrintWriter, die Buffered Stream Klassen etc... oft weiß ich nicht, welche Klasse ich am besten einsetze.

Ich habe nun die Situation, dass es eine Methode gibt, innerhalb derer ich einen String in den übergebenen OutputStream schreiben möchte.

Das sieht folgendermaßen aus:


```
public void write( OutputStream out )
{
	PrintWriter pw = new PrintWriter( out );
	pw.println( "Hello World" );
	pw.flush();
}
```

Mir stellt sich nun die Frage, warum ich pw.flush() machen muss (in einem Testprogramm ist der übergebene OutputStram "System.out" und ich sehe "Hello World" erst auf der Konsole, wenn ich pw.flush() aufrufe). Ist denn der PrintWriter auch gepuffert, obwohl es dafür extra BufferedXXX Klassen gibt?

Ist der code oben denn gut so? Oder sollte ich lieber einen BufferedWriter für soetwas verwenden, wie folgt:


```
public void write( OutputStream out )
{
	BufferedWriter bw = new BufferedWriter( new PrintWriter(out ) );
	
	try
	{
		bw.write( "Hello World!" );
		bw.flush();
	}
	catch ( IOException e ) { e.printStackTrace(); }
}
```

Hier habe ich den PrintWriter durch einen BufferedWriter gewrappt. Um die Ausgabe auf der Konsole zu sehen, muss ich wieder bw.flush() machen. Das kann ich aber verstehen, der die Ausgabe wird ja gepuffert. Aber warum muss ich denn bei einem BufferedWriter eine IOException abfangen, und beim PrintWriter nicht?


Ist das 2. Codebeispiel besser, oder gibt es einen noch anderen Weg, quasi eine Best Practice? Wie würdet Ihr die Geschichte lösen?


Danke für Eure Hilfe!


----------



## vfl_freak (16. Juli 2008)

Hallo,

also nach meinem Kenntnisstand kann man sich beim _PrintWriter_ in der Tat die _flush()_-Anweisung sparen (im Gegensatz zum _BufferedWriter_). 

Aber verstehe ich das jetzt richtig, dass es ohne das _flush()_ im ersten Beispiel gar nicht funktioniert 

tschüss
Klaus


----------



## takidoso (16. Juli 2008)

Also das zu Beantworten warum Flush beim PrintWriter gibt der Sourcecode sehr guten Aufschluß


```
...
    public PrintWriter(OutputStream out) {
	this(out, false);
    }

    /**
     * Creates a new PrintWriter from an existing OutputStream.  This
     * convenience constructor creates the necessary intermediate
     * OutputStreamWriter, which will convert characters into bytes using the
     * default character encoding.
     *
     * @param  out        An output stream
     * @param  autoFlush  A boolean; if true, the <tt>println</tt>,
     *                    <tt>printf</tt>, or <tt>format</tt> methods will
     *                    flush the output buffer
     *
     * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
     */
    public PrintWriter(OutputStream out, boolean autoFlush) {
	this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);
	// save print stream for error propagation
	if (out instanceof java.io.PrintStream) { 
	    psOut = (PrintStream) out;
	}
    }

...
```

Der Konstruktor, wie zu erkennen, verwendet bereits einen BufferedWriter. In der Einfachen Variante ohne Autoflush wird ein false als Default genommen!

Takidoso

PS: Die IO-Klassen sind in mancher Beziehung heftig viele. So ein Vererbungsbaum, den ich mal irgendwo in einem Buch gesehen hatte half meinem Verständnis in der ein oder anderen Weise gut auf die Sprünge.


----------



## vfl_freak (16. Juli 2008)

Hallo Takidoso,

ein guter Hinweis - Danke !!
Das war mir so auch nicht klar 

Habe eben mal die Sourcen der Projekte durchsucht, die ich hier vor einiger Zeit übernommen habe. Es gab nur eine einzige Stelle - und da wurde dann wohl auch genau dieses Autoflush verwendet .....

tschüss
Klaus


----------



## takidoso (16. Juli 2008)

DarthShader hat gesagt.:


> Hallo,
> 
> Ist das 2. Codebeispiel besser, oder gibt es einen noch anderen Weg, quasi eine Best Practice? Wie würdet Ihr die Geschichte lösen?
> 
> ...


Also Ich würde das erste Codebeispiel bevorzugen, da ich dem Sourcecode zur Folge im 2. Beispiel IMHO einen doppelten Puffer haben müsste, oder?


----------



## DarthShader (17. Juli 2008)

takidoso hat gesagt.:


> Also Ich würde das erste Codebeispiel bevorzugen, da ich dem Sourcecode zur Folge im 2. Beispiel IMHO einen doppelten Puffer haben müsste, oder?



Ja, das denke ich auch. Ich baue da im 2. Beispiel einen Buffer drum, aber der PritnWriter selbst baut auch nochmal einen Buffer, das ist sicher überflüssig. Das autoFlush habe ich total übersehen, danke für den Hinweis 

Ich bin mir allgemein recht unsicher, was ich genau für IO Klassen nehme. Immer wenn es im Input/Ouput geht, sehe ich mich durch die API suchen, was ich nun für Klassen nehme. Kennt vielleicht jemand eine Seite, wo genau diese Thematik mal aufgedröselt ist?

Danke


----------



## vfl_freak (17. Juli 2008)

Hi,

vielleicht hilft Dir ja Kapitel 13 im Online-Buch unter diesem Link :

http://www.tutego.com/javabuch/online.htm

tschüss
Klaus


----------

