This is an old revision of the document!
Τα προγράμματα χρησιμοποιούν byte streams για να εκτελέσουν είσοδο και έξοδο bytes των 8-bit. Όλες οι κατηγορίες byte stream είναι απόγονοι των InputStream και OutputStream.
Για να δείξουμε πώς δουλεύουν τα byte streams, θα ξεκινήσουμε από τις κλάσεις FileInputStream και FileOutputStream που είναι οι βασικότερες. Άλλες κλάσεις χτίζουν πάνω σε αυτές προκειμένου να προσφέρουν επιπλέον λειτουργικότητα.
Θα εξερευνήσουμε τις κλάσεις FileInputStream και FileOutputStream με χρήση του παρακάτω παραδείγματος CopyBytes, το οποίο λαμβάνει προς αντιγραφή ένα αρχείο από την γραμμή εντολών. Μπορείτε να χρησιμοποιήσετε ένα αρχείο κειμένου (π.χ. xanadu.txt) ή οποιαδήποτε εικόνα.
import java.io.*; public class CopyBytes { public static void main(String[] args) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { String filename; if(args.length > 0) filename = args[0]; else filename = "xanadu.txt"; in = new FileInputStream(filename); out = new FileOutputStream("__"+filename); int c; while ((c = in.read()) != -1) { out.write(c); } } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } }
Η μέθοδος main της κλάσης CopyBytes περνάει τον περισσότερο χρόνο επεξεργασίας μέσα σε ένα βρόχο που διαβάζει από το ρεύμα εισόδου και γράφει στο ρεύμα εξόδου ένα byte σε κάθε ανακύκλωση, όπως φαίνεται στην παρακάτω εικόνα.
Το κλείσιμο των streams που ανοίγουν είναι εξαιρετικά σημαντικό. Η κλάση CopyBytes χρησιμοποιεί ένα τελικό block για να εγγυηθεί ότι και τα δύο stream θα κλείσουν ακόμα και αν παρουσιαστεί κάποιο σφάλμα. Η πρακτική αυτή βοηθά στην αποφυγή διαρροής πόρων.
Ένα πιθανό σφάλμα είναι ότι το CopyBytes δεν μπόρεσε να ανοίξει το ένα ή και τα δύο αρχεία. Σε αυτή την περίπτωση θα παραχθεί ένα I/O Exception. Όταν συμβαίνει αυτό, η stream μεταβλητή θα έχει την τιμή null. Αυτός είναι ο λόγος για τον οποίο η κλάση CopyBytes φροντίζει ώστε κάθε stream μεταβλητή να περιέχει μια αναφορά αντικειμένου πριν από την κλήση του close.
Είδαμε ότι το παραπάνω πρόγραμμα δουλεύει τόσο με αρχεία κειμένου όσο και με δυαδικά αρχεία. Στις περιπτώσεις που θέλετε να γράψετε δυαδικά αρχεία, τα byte streams δουλεύουν εξαιρετικά. Εάν πάλι θέλετε να διαβάσετε και να γράψετε αρχεία κειμένου αφού προηγουμένως επεξεργαστείτε την πληροφορία κειμένου που διαβάσατε τότε τα streams χαρακτήρων (θα δούμε στη συνέχεια) είναι πιο ενδεδειγμένα.
Το παράδειγμα που είδαμε προηγουμένως το πρόγραμμα διαβάζει και γράφει ένα byte κάθε φορά. Προκειμένου να μπορούμε να χειριζόμαστε περισσότερα δεδομένα σε κάθε κλήση συστήματος, η πλατφόρμα της Java υλοποιεί τις κλάσεις BufferedInputStream και BufferedOutputStream για την διαχείριση ροών δεδομένων όπου διαβάζονται ή γράφονται περισσότερα του ενός byte κάθε φορά.
Παρακάτω θα ξαναγράψουμε το πρόγραμμα CopyBytes μόνο που αυτή τη φορά το διάβασμα των bytes δεν θα γίνει ένα-ένα (unbuffered), αλλά θα διαβάζονται και θα γράφονται ακολουθίες των 512 bytes με την βοήθεια των κλάσεων BufferedInputStream και BufferedOutputStream.
import java.io.*; public class CopyBufferedBytes { public static void main(String[] args) throws IOException { BufferedInputStream in = null; BufferedOutputStream out = null; final int buffer_size = 256; byte []buffer = new byte[buffer_size]; try { String filename; if(args.length > 0) filename = args[0]; else filename = "xanadu.txt"; in = new BufferedInputStream(new FileInputStream(filename)); out = new BufferedOutputStream(new FileOutputStream("__"+filename)); int size; while ((size = in.read(buffer, 0, buffer_size)) != -1) { out.write(buffer, 0, size); } } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } }
| Προηγούμενο: Είσοδος και έξοδος αρχείων | Περιεχόμενα | Επόμενο: Ροές Χαρακτήρων |