User Tools

Site Tools


java:byte_streams

This is an old revision of the document!


Ροές Δυαδικών Δεδομένων

Τα προγράμματα χρησιμοποιούν byte streams για να εκτελέσουν είσοδο και έξοδο bytes των 8-bit. Όλες οι κλάσεις τύπου byte-stream είναι απόγονοι των κλάσεων InputStream και OutputStream.

Για να δείξουμε πώς δουλεύουν τα byte streams, θα ξεκινήσουμε από τις κλάσεις FileInputStream και FileOutputStream που είναι οι βασικότερες. Άλλες κλάσεις χτίζουν πάνω σε αυτές προκειμένου να προσφέρουν επιπλέον λειτουργικότητα.

Χρησιμοποιώντας Byte Streams

Θα εξερευνήσουμε τις κλάσεις FileInputStream και FileOutputStream με χρήση του παρακάτω παραδείγματος CopyBytes, το οποίο λαμβάνει προς αντιγραφή ένα αρχείο από την γραμμή εντολών. Μπορείτε να χρησιμοποιήσετε ένα αρχείο κειμένου (π.χ. xanadu.txt) ή οποιαδήποτε εικόνα.

CopyBytes.java
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

Είδαμε ότι το παραπάνω πρόγραμμα δουλεύει τόσο με αρχεία κειμένου όσο και με δυαδικά αρχεία. Στις περιπτώσεις που θέλετε να γράψετε δυαδικά αρχεία, τα byte streams δουλεύουν εξαιρετικά. Εάν πάλι θέλετε να διαβάσετε και να γράψετε αρχεία κειμένου αφού προηγουμένως επεξεργαστείτε την πληροφορία κειμένου που διαβάσατε τότε τα streams χαρακτήρων (θα δούμε στη συνέχεια) είναι πιο ενδεδειγμένα.

Διαβάζοντας και γράφοντας περισσότερα από ένα bytes σε δυαδικό αρχείο

Το παράδειγμα που είδαμε προηγουμένως το πρόγραμμα διαβάζει και γράφει ένα byte κάθε φορά. Προκειμένου να μπορούμε να χειριζόμαστε περισσότερα δεδομένα σε κάθε κλήση συστήματος, η πλατφόρμα της Java υλοποιεί τις κλάσεις BufferedInputStream και BufferedOutputStream για την διαχείριση ροών δεδομένων όπου διαβάζονται ή γράφονται περισσότερα του ενός byte κάθε φορά.

Παρακάτω θα ξαναγράψουμε το πρόγραμμα 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 = "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();
      }
    }
  }
}
java/byte_streams.1582836047.txt.gz · Last modified: 2020/02/27 20:40 (external edit)