User Tools

Site Tools


java:character_streams

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:character_streams [2017/02/07 07:32] gthanosjava:character_streams [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
Line 1: Line 1:
-====== Streams Χαρακτήρων (Character Streams) ======+====== Ροές Χαρακτήρων (Character Streams) ======
  
-Η Java χρησιμοποιεί για την κωδικοποίηση χαρακτήρων τη σύμβαση UnicodeΟποιοδήποτε αρχείο περιέχει χαρακτήρες, για κάθε χαρακτήρα περιέχει την ισοδύναμη δυαδική μορφή του χαρακτήρα. Ένα character stream I/O μεταφράζει αυτόματα της δυαδικές τιμές σε unicode χαρακτήρες.+Η Java χρησιμοποιεί για την κωδικοποίηση χαρακτήρων τη μορφοποίηση [[https://en.wikipedia.org/wiki/UTF-16|UTF-16]]. Το πρότυπο UTF-16 κωδικοποιεί κάθε χαρακτήρα σε 2 bytes (max 65000 χαρακτήρες), ενώ μπορεί να κωδικοποιήσει χαρακτήρες και σε 4 bytes, εάν οι δυνατοί συνδυασμοί των 65000 χαρακτήρων αποδειχθούν μη επαρκείς. 
  
 ==== Χρησιμοποιώντας Streams Xαρακτήρων ==== ==== Χρησιμοποιώντας Streams Xαρακτήρων ====
  
-Όλες οι κλάσεις που περιγράφουν stream χαρακτήρων κατάγονται από τις κλάσεις [[https://docs.oracle.com/javase/7/docs/api/java/io/Reader.html|Reader]] και [[https://docs.oracle.com/javase/7/docs/api/java/io/Writer.html|Writer]]. Σε αναλογία και με τα byte streams που είδαμε προηγούμενα, υπάρχουν οι κλάσεις [[https://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html|FileReader]] και [[https://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html|FileWriter]] που επιτρέπουν την ανάγνωση και την εγγραφή streams χαρακτήρων από/σε αρχείο. Το παρακάτω παράδειγμα της κλάσης //CopyCharacters// παρουσιάζει τις κλάσεις αυτές.+Όλες οι κλάσεις που περιγράφουν streams χαρακτήρων κατάγονται από τις κλάσεις [[https://docs.oracle.com/javase/7/docs/api/java/io/Reader.html|Reader]] και [[https://docs.oracle.com/javase/7/docs/api/java/io/Writer.html|Writer]]. Σε αναλογία και με τα byte streams που είδαμε προηγούμενα, υπάρχουν οι κλάσεις [[https://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html|FileReader]] και [[https://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html|FileWriter]] που επιτρέπουν την ανάγνωση και τη μορφοποιημένη εγγραφή streams χαρακτήρων από/σε αρχείο. Το παρακάτω παράδειγμα της κλάσης //CopyCharacters// παρουσιάζει τις κλάσεις αυτές.
  
 <code java CopyCharacters.java> <code java CopyCharacters.java>
Line 15: Line 15:
   public static void main(String[] args) throws IOException {   public static void main(String[] args) throws IOException {
  
-    FileReader inputStream = null; +    String filename; 
-    FileWriter outputStream = null; +    if(args.length > 0) 
- +      filename = args[0]; 
-    try { +    else 
-      String filename; +      filename = "xanadu.txt"; 
-      if(args.length > 0) +     
-        filename = args[0]; +    try(FileReader reader = new FileReader(filename); 
-      else +        FileWriter writer = new FileWriter("__"+filename) 
-        filename = "xanadu.txt"; +       ) {
-       +
-      inputStream = new FileReader(filename); +
-      outputStream = new FileWriter("__"+filename); +
       int c;       int c;
-      while ((c = inputStream.read()) != -1) { +      while ((c = reader.read()) != -1) { 
-        outputStream.write(c); +        writer.write(c);
-      } +
-    } finally { +
-      if (inputStream != null) { +
-        inputStream.close(); +
-      } +
-      if (outputStream != null) { +
-        outputStream.close();+
       }       }
-    }+    } 
   }   }
 } }
 </code> </code>
  
-Η κλάση //CopyCharacters// είναι παρόμοια με την κλάση //CopyBytes//. Η σημαντικότερη διαφορά είναι ότι η //CopyCharacters// χρησιμοποιεί τις κλάσεις [[https://docs.oracle.com/javase/7/docs/api/java/io/Reader.html και [[https://docs.oracle.com/javase/7/docs/api/java/io/Writer.html|FileWriter]] για είσοδο και έξοδο στη θέση των FileInputStream και FileOutputStream. Παρατηρήστε ότι τόσο η κλάση //CopyBytes// όσο και η κλάση //CopyCharacters// χρησιμοποιούν μια μεταβλητή int για να διαβάσουν και να γράψουν. Ωστόσο, στο //CopyCharacters//, η μεταβλητή int κρατά μια τιμή χαρακτήρα στα 16 τελευταία bit του, ενώ στο CopyBytes, η μεταβλητή int κρατά μια byte τιμή στα τελευταία 8 bit του.+Η κλάση //CopyCharacters// είναι παρόμοια με την κλάση //CopyBytes//. Η διαφορά είναι ότι η //CopyCharacters// χρησιμοποιεί τις κλάσεις [[https://docs.oracle.com/javase/7/docs/api/java/io/Reader.html|FileReader]] και [[https://docs.oracle.com/javase/7/docs/api/java/io/Writer.html|FileWriter]] για είσοδο και έξοδο στη θέση των FileInputStream και FileOutputStream. Παρατηρήστε ότι τόσο η κλάση //CopyBytes// όσο και η κλάση //CopyCharacters// χρησιμοποιούν μια μεταβλητή int για να διαβάσουν και να γράψουν. Ωστόσο, στο //CopyCharacters//, η μεταβλητή int κρατά μια τιμή τύπου χαρακτήρα στα 16 τελευταία bit του ακεραίου, ενώ στο CopyBytes, η μεταβλητή int κρατά μια τιμή byte στα τελευταία 8 bit του ακεραίου.
  
 +===== Διαβάζοντας και γράφοντας γραμμή-γραμμή σε αρχείο κειμένου =====
  
-<WRAP tip 80% center round> +Παραπάνω είδαμε την ανάγνωση και εγγραφή ενός χαρακτήρα σε κάθε κλήση των μεθόδων read και write. Προκειμένου να διαχειριζόμαστε περισσότερους χαρακτήρες σε κάθε κλήση των read και write, επιλέγουμε να διαβάζουμε και να γράφουμε ομάδες χαρακτήρων. 
-Τα streams χαρακτήρων είναι «περιτυλίγματα» των byte streams. Κάθε stream χαρακτήρων χρησιμοποιεί το byte stream για την εκτέλεση της φυσικής I/O, ενώ το stream χαρακτήρων χειρίζεται τη μετάφραση μεταξύ των χαρακτήρων και bytes. Η κλάση [[https://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html|FileReader]], για παράδειγμα, χρησιμοποιεί την κλάση [[https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html|FileInputStream]], ενώ η [[https://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html|FileWriter]] χρησιμοποιεί την κλάση [[https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html|FileOutputStream]]. +
-</WRAP>+
  
-==== Buffered I/O ====+Μια συνηθισμένη ομαδοποίηση χαρακτήρων είναι η ομαδοποίηση ανά γραμμή. Η γραμμή ορίζεται ως μία σειρά από χαρακτήρες με ένα χαρακτήρα αλλαγής γραμμής στο τέλος. Ο χαρακτήρας αλλαγής γραμμής μπορεί να είναι μια ακολουθία χαρακτήρων carriege return/line feed ('\r''\n') για το λειτουργικό σύστημα Windows, ένας χαρακτήρας carriege return ('\r'), ή ένας χαρακτήρας line feed ('\n') για το λειτουργικό σύστημα GNU/Linux. 
  
-Τα περισσότερα από τα παραδείγματα που έχουμε δει μέχρι στιγμής χρησιμοποιούν //unbuffered// I / O. Αυτό σημαίνει ότι κάθε αίτημα ανάγνωσης ή εγγραφής χειρίζεται απευθείας από το υποκείμενο λειτουργικό σύστημα. Αυτό μπορεί να κάνει ένα πρόγραμμα πολύ λιγότερο αποτελεσματικό, δεδομένου ότι κάθε τέτοιο αίτημα, προκαλεί συχνά την πρόσβαση δίσκου, τη δραστηριότητα του δικτύου, ή κάποια άλλη ενέργεια που είναι σχετικά ακριβή.+Ας τροποποιήσουμε το παράδειγμα //CopyCharacters// για να διαβάσουμε και να γράψουμε γραμμήραμμή. Για να το κάνουμε αυτό, θα πρέπει να χρησιμοποιήσουμε δύο κλάσεις που δεν έχουμε ξαναδεί, τις [[https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html|BufferedReader]] και [[https://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html|PrintWriter]]
  
-Για να μειωθεί αυτό το είδος overhead, η πλατφόρμα της Java υλοποιεί //buffered// I / O streams. Τα buffered streams εισόδου διαβάζουν δεδομένα από μια περιοχή μνήμης που είναι γνωστή ως //buffer//. Ομοίως, τα buffered streams εξόδου γράφουν δεδομένα σε ένα //buffer//+Το παράδειγμα [[CopyLines]] επικαλείται τις [[http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()|BufferedReader.readLine]] και [[http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html#println()|PrintWriter.println]] για να διαβάσει και να γράψει μία γραμμή αντιστοίχως.
- +
-Ένα πρόγραμμα μπορεί να μετατρέψει ένα unbuffered stream  σε ένα buffered stream χρησιμοποιώντας το ιδίωμα περιτυλίγματος που έχουμε χρησιμοποιήσει αρκετές προηγούμενα, όπου το unbuffered stream περνά στον  constructor για μια buffered stream κλάση. Παρακάτω δίνεται πώς μπορείτε να τροποποιήσετε τις κλήσεις constructor στο παράδειγμα //CopyCharacters// για να χρησιμοποιούν buffered I / O: +
- +
-<code java> +
-inputStream = new BufferedReader(new FileReader("xanadu.txt")); +
-outputStream = new BufferedWriter(new FileWriter("characteroutput.txt")); +
-</code> +
- +
-Υπάρχουν τέσσερις κλάσεις τύπου buffered stream που χρησιμοποιούνται για να μετατρέψουν unbuffered streams σε buffered streams: Οι [[http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html|BufferedInputStream]] και [[http://docs.oracle.com/javase/7/docs/api/java/io/BufferedOutputStream.html|BufferedOutputStream]] δημιουργούν buffered byte streams, ενώ οι [[http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html|BufferedReader]] και [[http://docs.oracle.com/javase/7/docs/api/java/io/BufferedWriter.html|BufferedWriter]] δημιουργούν buffered streams χαρακτήρων.  +
- +
-==== Διαβάζοντας και γράφοντας γραμμή-γραμμή ==== +
- +
-Η διαδικασία ανάγνωσης ή διαβάσματος χαρακτήρων λαμβάνουν χώρα συνήθως σε ομάδες χαρακτήρων. Μια συνηθισμένη  ομάδα χαρακτήρων είναι η γραμμή. Η γραμμή ορίζεται ως μία σειρά από χαρακτήρες με ένα χαρακτήρα αλλαγής γραμμής στο τέλος. Ο χαρακτήρας αλλαγής γραμμής μπορεί να είναι μια ακολουθία χαρακτήρων carriege return/line feed ('\r''\n'), ένας χαρακτήρας carriege return ('\r'), ή ένας χαρακτήρας line feed ('\n').  +
- +
-Ας τροποποιήσουμε το παράδειγμα //CopyCharacters// για να χρησιμοποιήσουμε I/O χαρακτήρων για να διαβάσουμε και να γράψουμε γραμμή-γραμμή. Για να το κάνουμε αυτό, θα πρέπει να χρησιμοποιήσουμε δύο κλάσεις που δεν έχουμε ξαναδεί, τις [[https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html|BufferedReader]] και [[https://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html|PrintWriter]].  +
- +
-Το παράδειγμα [[CopyLines]] επικαλείται τις BufferedReader.readLine και PrintWriter.println για να διαβάσει και να γράψει μία γραμμή κάθε φορά.+
  
 <code java CopyLines.java> <code java CopyLines.java>
-import java.io.FileReader; +import java.io.*;
-import java.io.FileWriter; +
-import java.io.BufferedReader; +
-import java.io.PrintWriter; +
-import java.io.IOException;+
  
 public class CopyLines { public class CopyLines {
   public static void main(String[] args) throws IOException {   public static void main(String[] args) throws IOException {
 +    
 +    String filename;
 +    if(args.length > 0)
 +      filename = args[0];
 +    else
 +      filename = "xanadu.txt";
  
-    BufferedReader inputStream null+    try (BufferedReader reader new BufferedReader(new FileReader(filename))
-    PrintWriter outputStream null;+         PrintWriter writer new PrintWriter(new FileWriter("__"+filename)) 
 +        ) {
  
-    try { +      String line
-      String filename; +      while ((line reader.readLine()) != null) { 
-      if(args.length > 0) +        writer.println(line);
-        filename = args[0]; +
-      else +
-        filename = "xanadu.txt"; +
-         +
-      inputStream = new BufferedReader(new FileReader(filename)); +
-      outputStream = new PrintWriter(new FileWriter("__"+filename)); +
- +
-      String l+
-      while ((inputStream.readLine()) != null) { +
-        outputStream.println(l);+
       }       }
-    } finally { +    } 
-      if (inputStream != null) { +
-        inputStream.close(); +
-      } +
-      if (outputStream != null) { +
-        outputStream.close(); +
-      } +
-    }+
   }   }
 } }
 </code> </code>
  
-Η κλήση της //readline// επιστρέφει μια γραμμή κειμένου. To πρόγραμμα //CopyLines// εξάγει κάθε γραμμήχρησιμοποιώντας την //println//, η οποία προσθέτει τον χαρακτήρα αλλαγής γραμμής για το τρέχον λειτουργικό σύστημα. Αυτός μπορεί να μην είναι ο ίδιος χαρακτήρας αλλαγής γραμμής που χρησιμοποιήθηκε στο αρχείο εισόδου ή μπορεί να είναι διαφορετικός (εξαρτάται από το λειτουργικό σύστημα που χρησιμοποιήθηκε για την εγγραφή του αρχικού αρχείου).+<WRAP tip 80% center round> 
 +Η κλήση της //readline// επιστρέφει μια γραμμή κειμένου χωρίς τον χαρακτήρα αλλαγής γραμμής στο τέλος. Η κλάση //CopyLines// εξάγει κάθε γραμμή και την ξαναγράφει χρησιμοποιώντας την //println//, η οποία προσθέτει στο τέλος τον χαρακτήρα αλλαγής γραμμής ο οποίος απαλήφθηκε κατά την ανάγνωση. 
 +</WRAP>
  
 +Η ανάγνωση από πηγές χαρακτήρων συνήθως γίνεται από την κλάση java.util.Scanner, η οποία παρέχει τη δυνατότητα να ανάγνωσης κατά γραμμή, κατά λέξη ή την ανάγνωση βασικών τύπων όπως byte, short, int, double και float. Η κλάση java.util.Scanner εξετάζεται στην επόμενη ενότητα.
  
-|Προηγούμενο: [[:java:byte_streams | Byte Streams ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[java:formatting Μορφοποίηση Εξόδου ]]|+|Προηγούμενο: [[:java:byte_streams | Ροές Δεδομένων ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[java:util_scanner_class Η κλάση Scanner ]]|
java/character_streams.1486452726.txt.gz · Last modified: 2017/02/07 07:32 by gthanos