FileOutputStream write

J

Jessy12

Gast
Java:
package wahlfreierZugriff;

import java.io.*;
import java.util.Arrays;

public class Testen {
	public static void main(String[] args) throws Exception {
		String datei = "C:/users/jessy/desktop/java/last.txt";
		FileOutputStream wrt = new FileOutputStream(datei);
		wrt.write('A');
	}
}

Hallo, ich hffe jemand kann mir klar machen, warum das hier funktionieren muss. Die write-Methode hat doch als Parameter gar keinen char aber warum meckert der Compiler dann nicht? Des Weiteren, welchen Sinn macht write(int i), wenn doch eh nur die ersten 8 bit ausgelesen werden... Danke im Voraus :)
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
das geht weil auch
int x = 'A';
geht

und int als Parameter ist meiner Vermutung nach performanter im 32bit-Java (mit passenden Restprogramm),
und spart auch nervige Casts auf byte

ohne close() wird übrigens evtl. nichts gespeichert
 
N

nillehammer

Gast
- 'A' ist vom typ char und der lässt sich zu int upcasten. Deswegen meckert der Compiler nicht.
- write(int i) ist von der Oberklasse OutputStream vorgeschrieben und es werden tatsächlich nur die 8 low-order Bits gelesen. Was sich die JDK-Entwickler dabei gedacht haben? Keine Ahnung.
 
F

freak_007

Gast
Hallo,
In dem Falle wird ein char in int gecastet, weil ein char eigentlich eine Zahl ist. Aber umgekehrt brauchst ein cast, weil ein char weniger bits hat als ein int. Mit dem char du kannst mit chars genau dasselbe machen wie mit ints. Sowie
Java:
'a'++;
ist erlaubt.
Gruß,
Freak
 
J

Jessy12

Gast
Danke :)

Noch eine letzte Frage: Auch wenn ich sagen wir mal die Zahl 40 reinschreibe, so wird in der Textdatei nur das entsprechende ASCII-Zeichen angezeigt. Ich könnte das natürlich auch mit einem PrintStream lösen aber mich würde interessieren, wie es dazu kommt, dass eine 40 in der Textdatei übersetzt wird :)
 
J

Jessy12

Gast
Ich verstehe das mit der Kodierung nicht ganz. Wer sagt der Textdatei dass es eine A ist und keine 65
 
J

Jessy12

Gast
Ein FileReader liest 16 Bit und ein FileInputStream 8 bit. Das ist ja der einzige Unterschied. Trotzdem lesen beide immer nur ein Zeichen. Warum liest der Reader dann nicht gleich zwei Zeichen??
 

Ark

Top Contributor
Sowie
Java:
'a'++;
ist erlaubt.
Es ist zwar klar, was gemeint ist, aber genau so etwas geht nicht. ++ und -- dürfen/können nicht auf Konstanten angewandt werden, sonst wären es nämlich keine Konstanten. ;)

Ark

EDIT:
Ein FileReader liest 16 Bit […]
Jein. Wie viele Bytes/Bits ein Reader liest, hängt vom verwendeten Zeichensatz ab. Deine Aussage ist also im Allgemeinen falsch.
[…] und ein FileInputStream 8 bit. Das ist ja der einzige Unterschied. Trotzdem lesen beide immer nur ein Zeichen. Warum liest der Reader dann nicht gleich zwei Zeichen??
Gleiche Begründung: Es hängt vom Zeichensatz ab, wie viele Bytes zu wie vielen Zeichen dekodiert werden.

Es ist aber festgelegt, dass ein Reader in einem Schritt nur ein Zeichen ausspuckt. Möglicherweise liest also der Reader zwei Bytes ein und spuckt trotzdem nur ein Zeichen aus. Vielleicht liest er aber auch nur ein Byte ein und spuckt z.B. drei Zeichen aus (durch dreimaliges Aufrufen von [c]Reader.read()[/c])! Aus nur einem Byte macht er dir dann drei Zeichen! Wie das geht? Charset magic. :D

Ark
 
Zuletzt bearbeitet:
J

Jessy12

Gast
Beim Schreiben ist aber von Java her festgelegt wie viele Bits ich schreibe, oder? Wenn ich den falschen Zeichensatz wähle hat dann eben das Ausgabegerät Probleme mit diesem.

Beim Lesen muss ich aber vorher wissen, auf welchem Zeichensatz das Eingabegerät arbeitet und den entsprechenden Zeichensatz wählen.
 

Ark

Top Contributor
Beim Schreiben ist aber von Java her festgelegt wie viele Bits ich schreibe, oder?
Definiere "schreiben". Wenn du so was meinst wie "in eine Datei schreiben": Dafür kann man z.B. einen FileOutputStream verwenden. In diesen gibt man die zu schreibenden Informationen byteweise ein, ja. Aber das liegt jetzt nicht an der Programmiersprache Java selbst, sondern an der Spezifikation der Klasse OutputStream.

Ein OutputStreamWriter ist ein spezieller Writer. Deshalb gibt man in ihn Unicode-Zeichen (und nicht etwa Bytes) ein. Ein OutputStreamWriter weiß aber selbst, welchen OutputStream er bedienen soll. Wenn du also beim OutputStreamWriter, auf UTF-8 eingestellt ist, sagst, "schreibe das Zeichen ö", dann schreibt er von sich aus in den OutputStream zwei Bytes, weil das Zeichen ö UTF-8-kodiert eben zwei Bytes benötigt. Auch hier zeigt sich: Es ist alles Definitionssache. Habe ich nun das Zeichen ö oder zwei Bytes in die Datei geschrieben?

Ark
 
J

Jessy12

Gast
noch ein letzt mal melde ich mich :) Ein OutputstreamWriter dient ja dazu 2Byte große Daten in 1Byte große Daten umzuwandeln und dann an einen internen Stream weiterzugeben. Ich kann dem OutputStreamWriter aber auch sagen in welcher Codierung er die Daten weitergeben soll. Nun stellt sich mir die Frage: Wenn der OutputStreamWriter nur 1Byte große Daten an dein internen OutputStream weitergibt wieso kann ich dann die Kodierung "UTF-16" bspw. als Parameter wählen. Da stimmt doch was nicht...
 
S

SlaterB

Gast
> Ein OutputstreamWriter dient ja dazu 2Byte große Daten in 1Byte große Daten umzuwandeln
nein, wie kommst du darauf?
das mag möglich sein, etwa bei UTF-8 mit den häufigsten Zeichen,

aber dass Java an sich 2 Byte-Unicode verwendet, dass der char-Bereich bis 65.000 geht hat schon seinen Grund für all die ungewöhnlichen Zeichen,
und die brauchen dann eben mehr Platz, das kann niemand einfach so halbieren
 
J

Jessy12

Gast
Wie ist dann diese Aussasge in der Java-API zu verstehen?

An OutputStreamWriter is a bridge from character streams to byte streams: Characters written to it are encoded into bytes using a specified charset.
 
S

SlaterB

Gast
genau auf richtige Weise, was soll ich dazu sagen?
dort steht NICHT, dass '2Byte große Daten in 1Byte große Daten umzuwandeln' sind,
was meinst du sonst so unausgesprochen? was genau ist dir nicht klar?
 
J

Jessy12

Gast
warum steht da in der API "are written into Bytes"? wenn ich ein ö mit der Einstellung UTF-8 schreibe, dann ist es doch auch wieder 2 Bytes, also ein Character groß..
 
S

SlaterB

Gast
"are written into Bytes" ist kein Teil des zuvor geschriebenen Zitats,
aber was immer du auch meinst, es gibt einfach keine exakte Vorgabe der Anzahl Bytes,

10 Chars sind 10-20 Bytes im Normalfall, in exotischen Encodings vielleicht noch ganz anders,
in der allgemein Sicht auf Streams ist es ohne Sinn dort überhaupt an Details zu denken,
aus Chars werden Bytes, fertig, das ist exakt so richtig, mehr ist nicht zu sagen

normale Sätze in Goldwaagen zu interpretieren ist eh meist gefährlich,
wenn es was genaues zu sagen gibt, dann dürfte es meist auch so exakt formuliert sein wie z.B.:

In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive. The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.
Comparable (Java 2 Platform SE v1.4.2)
 

Volvagia

Top Contributor
Ein OSW ist eine Schnittstelle zwischen Writer (chars) und Streams (binär).
Bspw. kann man ihm für textbasierende Kommunikation über Sockets verwenden. Der Socket gibt einen Input/OutputStream zurück. Wenn ein Protokoll, wie z. B. der Steuerkanal von FTP auf textbasierende Kommunikation aufbaut (3 Zahlen + [Space + "Debug-Nachricht" +] Line wrappler) kannst du so chars ganz einfach per BufferedWriter(OutputStreamWriter(socket#getOutputStream())) verschicken. Ist aber nicht soooo gebräuchlich, weil Anfänger vor allem den PrintWriter verwenden (kA warum), aber beim Lesen kannst du so noch immer ganz einfach die Chars vom Socket über einen InputStreamReader bekommen.

Auch nur daran zu denken Daten per OSW zu "komprimieren" halte ich für groben Unfug.
 
Zuletzt bearbeitet:

Ark

Top Contributor
Ich vermute mal, das Verständnisproblem an der Stelle ist ein viel Grundsätzlicheres. Zumindest würde es mich nicht wundern, denn immerhin haben fast alle Menschen, die ich so kenne, das gleiche Problem (und das soll jetzt nicht heißen, dass ich davon verschont bliebe): Dies ist keine Pfeife.

(Es folgt ein Versuch, den Unterschied zwischen Daten und Informationen zu erklären.)

Ein Datum (lat. "Gegebenes", Plural: Daten) ist mehr oder weniger einfach da. Nehmen wir mal als Beispiel den Text, den du gerade liest. Für jemanden, der mit lateinischen Buchstaben nicht umgehen kann, ist das hier kein Text, noch weniger eine Folge lateinischer Buchstaben und noch viel weniger ist das hier für denjenigen (oder diejenige) ein deutscher Text. Zum besseren Verständnis: die meisten Deutsch-Muttersprachler sind nicht in der Lage, diese Folge von Schriftzeichen sicher der japanischen Sprache zuzuordnen, weil sie sie nicht von Chinesisch unterscheiden können. Sie können diese Schriftzeichen auch nicht richtig (mit der Hand) abschreiben, weil sie nicht wissen, worauf es ankommt. Ins Deutsche übertragen können sie es auch nicht.

Warum? Weil ihnen der richtige "Dekodierer" (decoder) fehlt: Decoder machen aus Daten Informationen, indem sie diesen Daten eine Bedeutung* geben. Menschen ohne Japanischkenntnisse können dem verlinkten Bild nicht die (vom Sender intendierte) richtige Information entlocken.

Nun zu Java & Co.: Ein InputStreamReader dekodiert eine Folge von Bytes zu einer Folge von Zeichen: eine Folge von Bits steht dann für das Zeichen A. Aber da ist kein A! Der ISR tut nur so, als hätte er gerade eines gelesen.** Information kann sich also auch z.B. durch entsprechende Reaktionen manifestieren.**

Wenn wir aber Information speichern oder übertragen wollen, müssen wir sie anders greifbar machen. Dies passiert z.B. im Rechner dadurch, dass bestimmte Stromflüsse geändert werden, die wiederum als 0 bzw. 1 interpretiert werden. Nun haben wir aber nicht unendlich viel Platz dafür, also begnügen wir uns mit nur wenigen Bits: das gelesene A überträgt der ISR an den Aufrufer, indem er es wieder als int kodiert(!) an ihn zurückgibt (er macht aus der Information "Zeichen A" wieder ein Datum).

Aber woher wissen wir, dass das, was der Reader zurückgibt, in diesem Fall für den Buchstaben A steht, und nicht für etwas anderes? Weil es für die read()-Methode so definiert wurde! Man hat sich gewissermaßen darauf geeinigt, dass das, was der Reader ausspuckt, als Unicode-Zeichen zu verstehen ist. Man hat sich auch darauf geeinigt, dass die 16 Bits in einem char als Unicode-Zeichen zu deuten sind. Im Gegensatz dazu werden die 16 Bits in einem short als Ganzzahl in Zweierkomplement-Darstellung gedeutet. Dass man mit chars rechnen kann, liegt nur daran, dass z.B. bei der Addition die 16 Bits des chars als natürliche Zahl gedeutet werden.

Es ist alles eine Sache der Definition, Interpretation usw. ;)

Ark

*: Gibt es für die Stelle ein besseres Wort?
**: Es ist schwierig bis unmöglich, dies wirklich "richtig" zu erklären. Ein Zen-Meister kann das wahrscheinlich besser als ich. :D
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Corben Input/Output FileOutputStream - neue Zeile mit write(10) Java Basics - Anfänger-Themen 6
F FileOutputStream.write Java Basics - Anfänger-Themen 2
hdi Datentypen FileOutputStream#write(int) mit ints? Java Basics - Anfänger-Themen 5
noah1407 Fileoutputstream Java Basics - Anfänger-Themen 4
S Datei-Speicherort von FileOutputStream Java Basics - Anfänger-Themen 4
M Fileoutputstream: Linux Dateinamen mit Umlaute Java Basics - Anfänger-Themen 4
J FileOutputStream aktuelle Speicher Pfad ausgeben Java Basics - Anfänger-Themen 13
J FileOutputStream Java Basics - Anfänger-Themen 3
A fileoutputstream ändern Java Basics - Anfänger-Themen 14
N FileOutputStream und existenz von Datei überprüfen Java Basics - Anfänger-Themen 2
O OOP FileOutputStream überschreibt ganzen inhalt der txt Java Basics - Anfänger-Themen 4
J FileOutputStream richtige Pfadangabe? Java Basics - Anfänger-Themen 8
A FileOutputStream -> byte[] (ohne File) Java Basics - Anfänger-Themen 6
G FileOutputStream generieren Java Basics - Anfänger-Themen 2
M FileOutputStream und zu große Zahlen! Java Basics - Anfänger-Themen 10
C FileInputStream und FileOutputStream Java Basics - Anfänger-Themen 4
A Instance methods should not write to "static" fields Java Basics - Anfänger-Themen 4
N Threads Read-Modify-Write Problem bei Multithreading (philosopher dining problem) Java Basics - Anfänger-Themen 5
S write(), weshalb verschiedene Ausgaben? Java Basics - Anfänger-Themen 4
K exec.StdIn.Write Java Basics - Anfänger-Themen 7
B Input/Output Socket I/O - outputStream.write(-1) Java Basics - Anfänger-Themen 2
X write() und Zufallszahlen Java Basics - Anfänger-Themen 2
K Input/Output read/write Java Basics - Anfänger-Themen 15
M Unterschied append / write aus der Klasse Writer Java Basics - Anfänger-Themen 2
W file read write crash Java Basics - Anfänger-Themen 2
M Audio Stream läuft auf :connection abort: socket write error Java Basics - Anfänger-Themen 2
M Pfad angabe bei getRescource und ImageIO.write Java Basics - Anfänger-Themen 4
G ImageIO.write() Java Basics - Anfänger-Themen 2
M Streams, read and write Java Basics - Anfänger-Themen 2
I ImageIO.write(bild, "was gibts da alles", pfad); Java Basics - Anfänger-Themen 6
D FileWriter write? Zeilenumbruch ? Java Basics - Anfänger-Themen 4
S Technik hinter der write Methode Java Basics - Anfänger-Themen 5
C write Java Basics - Anfänger-Themen 3
S Inhalt aus Array auf JSP anzeigen mit bean:write Java Basics - Anfänger-Themen 2
F javax.imageio.ImageIO write methode Java Basics - Anfänger-Themen 11

Ähnliche Java Themen

Neue Themen


Oben