User Tools

Site Tools


java:file_io_intro

Ροές δεδομένων

Για την ανάγνωση και εγγραφή από εξωτερικές πηγές η Java χρησιμοποιεί ροές πληροφορίας, οι οποίες ονομάζονται streams. Τα streams διακρίνονται σε InputStream για διάβασμα δεδομένων από μία πηγή και Output Stream για εγγραφή δεδομένων σε μία πηγή. Οι πηγές από τις οποίες μπορεί να διαβάσει ή στις οποίες μπορεί να γράψει ένα stream είναι πάρα πολλές. Για παράδειγμα ένα stream ανάγνωσης ή εγγραφής μπορεί να εφαρμοστεί σε αρχείο, σε ένα tcp/ip socket ή ακόμη και σε ένα πίνακα από bytes.

Ανεξάρτητα από το πώς λειτουργούν εσωτερικά, όλα τα streams παρουσιάζουν το ίδιο απλό μοντέλο στα προγράμματα που τα χρησιμοποιούν:

  • Ένα stream είναι μια ακολουθία πληροφορίας (ροή από bytes).
  • Ένα πρόγραμμα Java χρησιμοποιεί ένα input stream για να διαβάσει δεδομένα από μια πηγή.
  • Ένα πρόγραμμα Java χρησιμοποιεί ένα output stream για να γράψει δεδομένα σε έναν προορισμό.

Στις περιπτώσεις που θέλουμε να διαβάσουμε ροές χαρακτήρων (π.χ. αρχεία κειμένου), η Java παρέχει τις εξειδικευμένες κλάσεις java.io.Reader και java.io.Writer οι οποίες μετασχηματίζουν τη ροή χαρακτήρων σε ροή από bytes κατά την εγγραφή στην πηγή ή μετασχηματίζουν τη ροή από bytes σε ροή χαρακτήρων κατά την ανάγνωση από την πηγή. Οι κλάσεις τύπου java.io.Writer επιτρέπουν τη μορφοποιημένη εγγραφή πάνω στη ροή χαρακτήρων (λειτουργικότητα ανάλογη της printf στη γλώσσα C).

Οι κλάσεις στο πακέτο java.io για εγγραφή και ανάγνωση από απομακρυσμένες πηγές συνοψίζονται στις εξής:

Δυαδικά δεδομένα (ροές bytes) Δεδομένα κειμένου (ροές χαρακτήρων)
Input Output Input Output
Basic Class InputStream OutputStream Reader, InputStreamReader Writer, InputStreamWriter
Arrays ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
Files FileInputStream FileOutputStream FileReader FileWriter
Pipes PipedInputStream PipedOutputStream PipedReader PipedWriter
Strings StringReader StringWriter
Basic Data (big-endian format) DataInputStream DataOutputStream
Formatted Character Data PrintStream PrintWriter
Java Objects ObjectInputStream ObjectOutputStream
  • Οι κλάσεις ByteArrayInputStream και ByteArrayOutputStream διαβάζουν και γράφουν δυαδική πληροφορία πάνω σε ένα πίνακα από bytes. Αντίστοιχα οι κλάσεις CharArrayReader και CharArrayWriter διαβάζουν και γράφουν χαρακτήρες πάνω σε ένα πίνακα χαρακτήρων.
  • Οι κλάσεις FileInputStream και FileOutputStream διαβάζουν και γράφουν δυαδική πληροφορία σε ένα δυαδικό αρχείο. Αντίστοιχα οι κλάσεις FileReader και FileWriter διαβάζουν και γράφουν χαρακτήρες σε ένα αρχείο κειμένου (αρχείο που περιέχει αποκλειστικά πληροφορία χαρακτήρων). Κατά την ανάγνωση ή εγγραφή με χρήση των κλάσεων FileReader και FileWriter ΔΕΝ μπορείτε να προσδιορίσετε την κωδικοποίηση των χαρακτήρων που περιέχονται στο αρχείο. Οι κλάσεις αυτές δουλεύουν με την default κωδικοποίηση των χαρακτήρων στη Java που είναι UTF-16. Εναλλακτικά, μπορείτε να χρησιμοποιήσετε τις κλάσεις InputStreamReader και InputStreamWriter, οι οποίες δέχονται ως ορίσματα ένα InputStream (FileInputStream στη συγκεκριμένη περίπτωση) και μία επιπλέον παράμετρο που αφορά την κωδικοποίηση των χαρακτήρων που περιέχει το αρχείο.
  • Οι κλάσεις PipedInputStream, PipedOutputStream και PipedReader, PipedWriter χρησιμοποιούνται για την επικοινωνία μεταξύ νημάτων εντός της ίδιας διεργασίας (inter-thread communication).
  • Οι κλάσεις DataInputStream και DataOutputStream χρησιμοποιούνται για την ανάγνωση και εγγραφή βασικών τύπων δεδομένων (short, int, long, float, double, boolean κλπ) πάνω από μία ροή δυαδικής πληροφορίας. Προϋπόθεση για την χρήση των παραπάνω κλάσεων είναι τα δεδομένα να γράφονται ή να διαβάζονται κατά big-endian.
  • Οι κλάσεις PrintStream και PrintWriter χρησιμοποιούνται για την εγγραφή μορφοποιημένης πληροφορίας χαρακτήρων (σε αναλογία με την printf στη γλώσσα C). Και οι δύο κλάσεις έχουν ανάλογη λειτουργικότητα αν και η λογική με την οποία έχουν υλοποιηθεί είναι διαφορετική. Ενδεικτικά, δείτε το παρακάτω πρόγραμμα και εξετάστε τα αρχεία file1.txt και file2.txt με ένα hex editor.
PrintStreamVsPrintWriter.java
import java.io.*;
 
public class PrintStreamVsPrintWriter {
  public static void main(String []args) {
    try(PrintStream st = new PrintStream(new File("file1.txt"));
        PrintWriter wr = new PrintWriter(new File("file2.txt"))
       ) {
       st.print("Πως είσαι;");
       st.print(1.2345);
       wr.print("Πως είσαι;");
       wr.print(1.2345);
    }
    catch(IOException ex) {
    }
  }
}
  • Οι κλάσεις ObjectInputStream και ObjectOutputStream υλοποιούν τη σειριοποίηση αντικειμένων ώστε αυτά να αποθηκευτούν σε αρχεία ή να αποσταλούν σε απομακρυσμένους προορισμούς (συνήθως μέσω sockets). Τα αντικείμενα, αφού ανακτηθούν στο προορισμό τους μπορούν να είναι λειτουργικά από το πρόγραμμα προορισμού.

Είσοδος και έξοδος από την κονσόλα

Προκειμένου να διαβάσετε και να γράψετε από την κονσόλα η Java διαθέτει την κλάση System, η οποία διαθέτει 3 στατικές μεταβλητές τύπου Stream. Συγκεκριμένα, διατίθενται τα streams (τύπου PrintStream) System.out (STDOUT) και System.err (STDERR) για γράψιμο στην κονσόλα, καθώς και το stream (τύπου InputStream)System.in (STDIN) για διάβασμα από την κονσόλα.

Στις επόμενες ενότητες θα δούμε παραδείγματα εκτύπωσης και διαβάσματος από την κονσόλα.

java/file_io_intro.txt · Last modified: 2021/03/29 06:28 (external edit)