This is an old revision of the document!
Table of Contents
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 χαρακτήρων.
Διαβάζοντας και γράφοντας περισσότερα bytes σε δυαδικό αρχείο
Παρακάτω θα ξαναγράψουμε το πρόγραμμα CopyBytes μόνο που αυτή τη φορά το διάβασμα των bytes δεν θα γίνει ένα-ένα (unbuffered), αλλά θα διαβάζονται και θα γράφονται ακολουθίες των 512 bytes με την βοήθεια των κλάσεων BufferedInputStream και BufferedOutputStream.
- CopyBufferedBytes.java
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 = "lena.jpg"; 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(); } } } }
Διαβάζοντας και γράφοντας γραμμή-γραμμή σε αρχείο κειμένου
Η διαδικασία ανάγνωσης ή διαβάσματος χαρακτήρων λαμβάνουν χώρα συνήθως σε ομάδες χαρακτήρων. Μια συνηθισμένη ομάδα χαρακτήρων είναι η γραμμή. Η γραμμή ορίζεται ως μία σειρά από χαρακτήρες με ένα χαρακτήρα αλλαγής γραμμής στο τέλος. Ο χαρακτήρας αλλαγής γραμμής μπορεί να είναι μια ακολουθία χαρακτήρων 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.*; public class CopyLines { public static void main(String[] args) throws IOException { BufferedReader inputStream = null; PrintWriter outputStream = null; try { String filename; if(args.length > 0) filename = args[0]; else filename = "xanadu.txt"; inputStream = new BufferedReader(new FileReader(filename)); outputStream = new PrintWriter(new FileWriter("__"+filename)); String l; while ((l = inputStream.readLine()) != null) { outputStream.println(l); } } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } } }
Η κλήση της readline επιστρέφει μια γραμμή κειμένου. Η κλάση CopyLines εξάγει κάθε γραμμή, χρησιμοποιώντας την println, η οποία προσθέτει τον χαρακτήρα αλλαγής γραμμής για το τρέχον λειτουργικό σύστημα.