User Tools

Site Tools


java:character_streams

Ροές Χαρακτήρων (Character Streams)

Η Java χρησιμοποιεί για την κωδικοποίηση χαρακτήρων τη μορφοποίηση UTF-16. Το πρότυπο UTF-16 κωδικοποιεί κάθε χαρακτήρα σε 2 bytes (max 65000 χαρακτήρες), ενώ μπορεί να κωδικοποιήσει χαρακτήρες και σε 4 bytes, εάν οι δυνατοί συνδυασμοί των 65000 χαρακτήρων αποδειχθούν μη επαρκείς.

Χρησιμοποιώντας Streams Xαρακτήρων

Όλες οι κλάσεις που περιγράφουν streams χαρακτήρων κατάγονται από τις κλάσεις Reader και Writer. Σε αναλογία και με τα byte streams που είδαμε προηγούμενα, υπάρχουν οι κλάσεις FileReader και FileWriter που επιτρέπουν την ανάγνωση και τη μορφοποιημένη εγγραφή streams χαρακτήρων από/σε αρχείο. Το παρακάτω παράδειγμα της κλάσης CopyCharacters παρουσιάζει τις κλάσεις αυτές.

CopyCharacters.java
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class CopyCharacters {
  public static void main(String[] args) throws IOException {
 
    String filename;
    if(args.length > 0)
      filename = args[0];
    else
      filename = "xanadu.txt";
 
    try(FileReader reader = new FileReader(filename);
        FileWriter writer = new FileWriter("__"+filename)
       ) {
      int c;
      while ((c = reader.read()) != -1) {
        writer.write(c);
      }
    } 
  }
}

Η κλάση CopyCharacters είναι παρόμοια με την κλάση CopyBytes. Η διαφορά είναι ότι η CopyCharacters χρησιμοποιεί τις κλάσεις FileReader και FileWriter για είσοδο και έξοδο στη θέση των FileInputStream και FileOutputStream. Παρατηρήστε ότι τόσο η κλάση CopyBytes όσο και η κλάση CopyCharacters χρησιμοποιούν μια μεταβλητή int για να διαβάσουν και να γράψουν. Ωστόσο, στο CopyCharacters, η μεταβλητή int κρατά μια τιμή τύπου χαρακτήρα στα 16 τελευταία bit του ακεραίου, ενώ στο CopyBytes, η μεταβλητή int κρατά μια τιμή byte στα τελευταία 8 bit του ακεραίου.

Διαβάζοντας και γράφοντας γραμμή-γραμμή σε αρχείο κειμένου

Παραπάνω είδαμε την ανάγνωση και εγγραφή ενός χαρακτήρα σε κάθε κλήση των μεθόδων read και write. Προκειμένου να διαχειριζόμαστε περισσότερους χαρακτήρες σε κάθε κλήση των read και write, επιλέγουμε να διαβάζουμε και να γράφουμε ομάδες χαρακτήρων.

Μια συνηθισμένη ομαδοποίηση χαρακτήρων είναι η ομαδοποίηση ανά γραμμή. Η γραμμή ορίζεται ως μία σειρά από χαρακτήρες με ένα χαρακτήρα αλλαγής γραμμής στο τέλος. Ο χαρακτήρας αλλαγής γραμμής μπορεί να είναι μια ακολουθία χαρακτήρων carriege return/line feed ('\r''\n') για το λειτουργικό σύστημα Windows, ένας χαρακτήρας carriege return ('\r'), ή ένας χαρακτήρας line feed ('\n') για το λειτουργικό σύστημα GNU/Linux.

Ας τροποποιήσουμε το παράδειγμα CopyCharacters για να διαβάσουμε και να γράψουμε γραμμή-γραμμή. Για να το κάνουμε αυτό, θα πρέπει να χρησιμοποιήσουμε δύο κλάσεις που δεν έχουμε ξαναδεί, τις BufferedReader και PrintWriter.

Το παράδειγμα CopyLines επικαλείται τις BufferedReader.readLine και PrintWriter.println για να διαβάσει και να γράψει μία γραμμή αντιστοίχως.

CopyLines.java
import java.io.*;
 
public class CopyLines {
  public static void main(String[] args) throws IOException {
 
    String filename;
    if(args.length > 0)
      filename = args[0];
    else
      filename = "xanadu.txt";
 
    try (BufferedReader reader = new BufferedReader(new FileReader(filename));
         PrintWriter writer = new PrintWriter(new FileWriter("__"+filename))
        ) {
 
      String line;
      while ((line = reader.readLine()) != null) {
        writer.println(line);
      }
    } 
  }
}

Η κλήση της readline επιστρέφει μια γραμμή κειμένου χωρίς τον χαρακτήρα αλλαγής γραμμής στο τέλος. Η κλάση CopyLines εξάγει κάθε γραμμή και την ξαναγράφει χρησιμοποιώντας την println, η οποία προσθέτει στο τέλος τον χαρακτήρα αλλαγής γραμμής ο οποίος απαλήφθηκε κατά την ανάγνωση.

Η ανάγνωση από πηγές χαρακτήρων συνήθως γίνεται από την κλάση java.util.Scanner, η οποία παρέχει τη δυνατότητα να ανάγνωσης κατά γραμμή, κατά λέξη ή την ανάγνωση βασικών τύπων όπως byte, short, int, double και float. Η κλάση java.util.Scanner εξετάζεται στην επόμενη ενότητα.

java/character_streams.txt · Last modified: 2021/04/04 16:20 (external edit)