java:character_streams

Streams Χαρακτήρων (Character Streams)

Η Java χρησιμοποιεί για την κωδικοποίηση χαρακτήρων τη σύμβαση Unicode. Οποιοδήποτε αρχείο περιέχει χαρακτήρες, για κάθε χαρακτήρα περιέχει την ισοδύναμη δυαδική μορφή του χαρακτήρα. Ένα character stream I/O μεταφράζει αυτόματα της δυαδικές τιμές σε unicode χαρακτήρες.

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

Όλες οι κλάσεις που περιγράφουν stream χαρακτήρων κατάγονται από τις κλάσεις 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 {
 
        FileReader inputStream = null;
        FileWriter outputStream = null;
 
        try {
            inputStream = new FileReader("xanadu.txt");
            outputStream = new FileWriter("characteroutput.txt");
 
            int c;
            while ((c = inputStream.read()) != -1) {
                outputStream.write(c);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}

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

Streams Xαρακτήρων που χρησιμοποιούν Byte Streams

Τα streams χαρακτήρων είναι συχνά «περιτυλίγματα» των byte streams. Κάθε stream χαρακτήρων χρησιμοποιεί το byte stream για την εκτέλεση της φυσικής I/O, ενώ το stream χαρακτήρων χειρίζεται τη μετάφραση μεταξύ των χαρακτήρων και bytes. Η κλάση FileInputStream, ενώ η FileWriter χρησιμοποιεί την κλάση FileOutputStream.

Διαβάζοντας και γράφοντας μία γραμμή

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

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

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

CopyLines.java
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
 
public class CopyLines {
    public static void main(String[] args) throws IOException {
 
        BufferedReader inputStream = null;
        PrintWriter outputStream = null;
 
        try {
            inputStream = new BufferedReader(new FileReader("xanadu.txt"));
            outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
 
            String l;
            while ((l = inputStream.readLine()) != null) {
                outputStream.println(l);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}

Η κλήση της readline επιστρέφει μια γραμμή κειμένου. To πρόγραμμα CopyLines εξάγει κάθε γραμμή, χρησιμοποιώντας την println, η οποία προσθέτει τον χαρακτήρα αλλαγής γραμμής για το τρέχον λειτουργικό σύστημα. Αυτός μπορεί να μην είναι ο ίδιος χαρακτήρας αλλαγής γραμμής που χρησιμοποιήθηκε στο αρχείο εισόδου ή μπορεί να είναι διαφορετικός (εξαρτάται από το λειτουργικό σύστημα που χρησιμοποιήθηκε για την εγγραφή του αρχικού αρχείου).

Buffered I/O

Τα περισσότερα από τα παραδείγματα που έχουμε δει μέχρι στιγμής χρησιμοποιούν unbuffered I / O. Αυτό σημαίνει ότι κάθε αίτημα ανάγνωσης ή εγγραφής χειρίζεται απευθείας από το υποκείμενο λειτουργικό σύστημα. Αυτό μπορεί να κάνει ένα πρόγραμμα πολύ λιγότερο αποτελεσματικό, δεδομένου ότι κάθε τέτοιο αίτημα, προκαλεί συχνά την πρόσβαση δίσκου, τη δραστηριότητα του δικτύου, ή κάποια άλλη ενέργεια που είναι σχετικά ακριβή.

Για να μειωθεί αυτό το είδος overhead, η πλατφόρμα της Java υλοποιεί buffered I / O streams. Τα buffered streams εισόδου διαβάζουν δεδομένα από μια περιοχή μνήμης που είναι γνωστή ως buffer. Ομοίως, τα buffered streams εξόδου γράφουν δεδομένα σε ένα buffer.

Ένα πρόγραμμα μπορεί να μετατρέψει ένα unbuffered stream σε ένα buffered stream χρησιμοποιώντας το ιδίωμα περιτυλίγματος που έχουμε χρησιμοποιήσει αρκετές προηγούμενα, όπου το unbuffered stream περνά στον constructor για μια buffered stream κλάση. Παρακάτω δίνεται πώς μπορείτε να τροποποιήσετε τις κλήσεις constructor στο παράδειγμα CopyCharacters για να χρησιμοποιούν buffered I / O:

inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));

Υπάρχουν τέσσερις κλάσεις τύπου buffered stream που χρησιμοποιούνται για να μετατρέψουν unbuffered streams σε buffered streams: Οι BufferedInputStream και BufferedOutputStream δημιουργούν buffered byte streams, ενώ οι BufferedReader και BufferedWriter δημιουργούν buffered streams χαρακτήρων.

Προηγούμενο: Byte Streams Επόμενο: Μορφοποίηση Εξόδου
java/character_streams.txt · Last modified: 2016/02/26 11:15 (external edit)