2017-10-22 1 views
1

Ich arbeite an I/O-Klassen in Java. Ich verstehe, dass es zwei wichtige Arten von Streams gibt: Byte-Stream und Zeichen-Stream. Aber ... Ich habe versucht, Textdatei mit Byte-Stream zu lesen und zu schreiben, und es hat funktioniert. Hier ist der Code:Byte Stream vs Zeichen Stream in Java

File klasor = new File("C:\\Java"); 
    if(!klasor.exists()) klasor.mkdirs(); 

    File kaynakDosya = new File("C:\\Java\\kaynak.txt"); 
    if(!kaynakDosya.exists()) kaynakDosya.createNewFile(); 

    File hedefDosya = new File("C:\\Java\\hedef.txt"); 
    if(!hedefDosya.exists()) hedefDosya.createNewFile(); 

    FileInputStream kaynak = new FileInputStream(kaynakDosya); 
    FileOutputStream hedef = new FileOutputStream(hedefDosya); 

    int c; 
    while((c = kaynak.read()) != -1) { 
     hedef.write(c); 
    } 

    if(kaynak != null) { 
     kaynak.close(); 
    } 

    if(hedef != null) { 
     hedef.close(); 
    } 

Und dann habe ich das gleiche mit Zeichenstrom:

File klasor = new File("C:\\Java"); 
    if(!klasor.exists()) klasor.mkdirs(); 

    File kaynakDosya = new File("C:\\Java\\kaynak.txt"); 
    if(!kaynakDosya.exists()) kaynakDosya.createNewFile(); 

    File hedefDosya = new File("C:\\Java\\hedef.txt"); 
    if(!hedefDosya.exists()) hedefDosya.createNewFile(); 

    FileReader kaynak = new FileReader(kaynakDosya); 
    FileWriter hedef = new FileWriter(hedefDosya); 

    int c; 
    while((c = kaynak.read()) != -1) { 
     hedef.write(c); 
    } 

    if(kaynak != null) { 
     kaynak.close(); 
    } 

    if(hedef != null) { 
     hedef.close(); 
    } 

Diese beiden das gleiche Ergebnis. Also, ich möchte wissen, warum sollte ich nicht Byte-Stream hier aber Zeichenstrom verwenden? (Ich habe einige Artikel sowie verwandte Fragen hier auf stackoverflow gelesen und sie sagen es) Ich weiß, dass der Zeichenstrom Zeichen für Zeichen lesen wird, aber welchen Vorteil hat das für mich? Oder welche Probleme könnten auftreten, wenn ich Zeichen mit Byte-Stream lese? Ich hoffe meine Frage ist klar. Ich würde gerne Fallbeispiele schätzen.

Antwort

1

java.io.FileInputStream Javadoc- Zustände:

Fileinputstream ist gedacht für die Ströme der unformatierten Bytes wie Bilddaten zu lesen. Verwenden Sie zum Lesen von Zeichenströmen die Verwendung von FileReader.

java.io.FileOutputStream javadoc Staaten etwas ähnlich genug:

Outputstream zum Schreiben Strom von rohem Bytes wie Bilddaten gemeint ist. Verwenden Sie für das Schreiben von Zeichenströmen die Verwendung von FileWriter.

Ein Hauptunterschiede zwischen FileInputStream/FileOutputStream und FileReader/FileWriter ist, dass das erste Verfahren liefert Bytes zu manipulieren, während die letztere Verfahren bietet Zeichen zu manipulieren.

In Ihrem Beispiel, wenn Sie einen Dateiinhalt in eine andere Datei kopieren, macht das Manipulieren von char oder byte keinen großen Unterschied.
In Ihrem Fall scheint ein FileInputStream oder ein BufferedInputStream noch angemessener.

Aber wenn Sie verwenden einen Strom/Schreib-Zeichen aus/in String Instanzen zu lesen, mit FileReader/FileWriter erleichtert wirklich die Dinge und die Dinge klarer.
Außerdem können Sie auch FileReader/FileWriter in eine BufferedReader/BufferedWriter umbrechen und von effizientem Lesen/Schreiben von Zeichen, Arrays und Zeilen profitieren.

BufferedWriter writer = new BufferedWriter(new FileWriter("myfile")); 
writer.append(oneString); 
writer.append(oneStringBuffer); 
writer.newLine(); 

BufferedReader reader = new BufferedReader(new FileReader("myfile")); 
String currentLine = reader.readLine(); 
0

Zeichen auf einen byte-orientierte Ausgangsstrom (oder Lesen von Zeichen aus einem byteorientierten Eingabestrom) Schreiben werden die gleichen Ergebnisse wie unter Verwendung von zeichenorientierten Strömen nur erzeugen, wenn alle der Zeichen in dem Strom sein können, dargestellt durch einzelne Bytes in der Standard-Codierung Ihrer Plattform (in der Regel UTF-8, aber es könnte etwas anderes sein). Um dies zu testen, versuchen Sie eine Datei, die etwas enthält, das mehr als ein Byte zur Darstellung benötigt (z. B. griechische, kyrillische oder arabische Zeichen). Bei einem byte-orientierten Stream funktionieren diese nicht. Bei einem zeichenorientierten Stream bleiben die Zeichen erhalten, solange beide Streams Codierungen verwenden, die diese Zeichen unterstützen (z. B. UTF-8), und die Eingabedatei wurde in der Codierung gespeichert, die für den Eingabestream verwendet wird.

Beachten Sie, dass Ihr Byte-orientierter Code dies nicht tatsächlich testet, da es nur eine Byte-für-Byte-Datei kopiert. Alles wird so aussehen, als würde es funktionieren, aber wenn Sie versuchen würden, die tatsächlichen Zeichen zu lesen (zum Beispiel, um sie mit dem tatsächlichen Text im Code zu vergleichen, würde es scheitern. Um dies zu testen, erstellen Sie eine Datei (in, sagen wir, UTF-8-Codierung) . kyrillische Text „! Привет“ Dann im Code, versuchen Sie diesen Text liest ein byteorientierte Eingangsstrom in einen String und Tests zu verwenden, wenn es tatsächlich enthält, was Sie

System.out.println("Success: " + "Привет!".equals(input)); 
+0

mit erwarte ich bin verwirrt: nicht alle die Zeichen, die durch zwei Bytes dargestellt werden? Was meinen Sie mit "wenn alle Zeichen in der Datei durch einzelne Bytes dargestellt werden können?" Ich habe es mit kyrillischem "Привет!" versucht und es hat auch funktioniert! Plus, ich habe habe die Codierung der Quelldatei "UTF-8" beibehalten und die Kodierung der Zieldatei in "ANSI" geändert, es hat trotzdem funktioniert. –

+0

@AdemTepe - In UTF-8, Codepunkte bis zu 0x7F werden durch ein einzelnes Byte dargestellt. (Siehe [this thread] (https://stackoverflow.com/questions/7136421/why-does-utf-8-use-more-than-one-byte-to-represent-some-characters), zum Beispiel.) Ihr Byte-orientierter Code eignet sich gut, um eine Datei byteweise zu kopieren, aber dies behandelt nicht, was passieren würde, wenn Sie versuchen würden, diese Bytes als Zeichen zu interpretieren oder wenn Sie versuchten, Zeichen in ein Byte zu schreiben -orientierten Strom. Ich werde meine Antwort aktualisieren, um diesen Punkt zu klären. –