Table of Contents

Διαβάζοντας από ένα αρχείο

Στην προηγούμενη παράγραφο είδαμε πως μπορούμε να δημιουργήσουμε ένα αντικείμενο της κλάσης File, αλλά και πως μπορούμε να πλοηγηθούμε στους καταλόγους του filesystem του υπολογιστή μας. Στην παρούσα σελίδα θα δούμε εναλλακτικούς τρόπους με τους οποίους μπορούμε να διαβάσουμε από ένα αρχείο κειμένου. Για τα παραδείγματα που ακολουθούν υποθέστε ότι καλούμαστε να διαβάσουμε το παρακάτω αρχείο που περιέχει τα ονόματα και τα τηλέφωνα ενός τηλεφωνικού καταλόγου.

telephone-list.txt
John Smith, 6944854544
Robert Parson, 6978456123
Nick Carlson, 6982147852
Barbara Miller, 6978852456
Max Taylor, 6936785412

Τα οποία θέλουμε να τα αποθηκεύσουμε σε ένα πίνακα από αντικείμενα της παρακάτω κλάσης TelephoneNumber

TelephoneNumber.java
public class TelephoneNumber {
  private String name;
  private String number;
 
  public TelephoneNumber(String newName, String newNumber) {
    name = newName;
    number = newNumber;
  }
 
  public String getName() { return name; }
  public String getNumber() { return number; }
  public void setName(String newName) { name = newName; }
  public void setNumber(String newNumber) { number = newNumber; }
 
  public String toString() {
    return "Name: "+name+", Number: "+number;
  }
}

Διαβάζοντας γραμμή-γραμμή

Ό πιο απλός τρόπος ανάγνωσης αρχείων κειμένου είναι το διάβασμα κάθε γραμμής ξεχωριστά και στη συνέχει η επεξεργασία της γραμμής, ώστε να εξάγουμε τα αποτελέσματα που θέλουμε. Προκειμένου να επιτύχετε το διάβασμα ενός αρχείου γραμμή-γραμμή μπορείτε να το κάνετε με χρήση της κλάσης java.io.BufferedReader, όπως φαίνεται παρακάτω:

ReadLineByLine.java
import java.io.*;
 
public class ReadLineByLine {
  public static void main(String []args) {
    try {
      String input;
      int i=0;
      TelephoneNumber [] numbers = new TelephoneNumber[5];
      BufferedReader in = new BufferedReader(new FileReader("telephone-list.txt"));
      while( (input = in.readLine()) != null && input.length() > 0 ) {
        numbers[i++] = createTelephoneNumber(input);
      }
      System.out.println("-------- Telephone Numbers ---------");
      for(TelephoneNumber number : numbers) {
        System.out.println(number);
      }
    } catch( IOException ex ) {
      ex.printStackTrace();
    }
  }
 
  public static TelephoneNumber createTelephoneNumber(String inputLine) {
    int commaPosition = inputLine.indexOf(",");
    String name = inputLine.substring(0, commaPosition).trim();
    String telephone = inputLine.substring( commaPosition+1 ).trim();
    TelephoneNumber t = new TelephoneNumber(name, telephone);
    return t;
  }
}

H δήλωση της μορφής

  try {
    // some code here
  } catch(Exception ex) {
    ex.printStackTrace();
  }

δηλώνει την πιθανή ύπαρξη ενός exception στον κώδικα που περιέχεται μέσα στο try μπλοκ. Τη χρήση των exceptions θα την δούμε αναλυτικά στη συνέχεια.

Χρησιμοποιώντας την κλάση Scanner

Εκτός από την δυνατότητα που έχετε να διαβάζετε γραμμή-γραμμή η Java σας δίνει την επιπλέον δυνατότητα να διαβάζετε συγκεκριμένους τύπους δεδομένων μέσω της κλάσης java.util.Scanner. Η κλάση Scanner σας δίνει την δυνατότητα να διαβάζετε από ένα αρχείο ή από την κονσόλα τα δεδομένα σας είτε ως primitive τύπους δεδομένων (int, byte, long, double κλπ), είτε ως String. Επίσης σας δίνει την δυνατότητα να διαβάσετε μία ολόκληρη γραμμή, όπως κάνατε και με χρήση της κλάσης java.io.BufferedReader.

Οι μέθοδοι της κλάσης Scanner έχουν συνοπτικά ως εξής:

Κατασκευαστές

Ένα αρχείο μπορείτε να το ανοίξετε είτε με χρήση της κλάσης File που είδαμε νωρίτερα είτε με χρήση της κλάσης java.io.InputStream, προκειμένου να χρησιμοποιήσετε την κλάση Scanner. Δείτε τα παραδείγματα χρήσης που ακολουθούν.

Μέθοδοι

Παράδειγμα ανάγνωσης με χρήση της Scanner

ReadWithScanner.java
import java.util.Scanner;
import java.io.File;
 
public class ReadWithScanner {
  public static void main(String []args) {
    String firstname=null, lastname=null, number=null;
    int i=0;
    TelephoneNumber numbers[] = new TelephoneNumber[5];
    try {
      Scanner sc = new Scanner(new File("telephone-list.txt"));
 
      while( sc.hasNext() ) {        
        firstname = sc.next();
        lastname = sc.next();
        number = sc.next();
 
        if( lastname.charAt( lastname.length() -1 ) == ',' ) 
          lastname = lastname.substring(0, lastname.length() -1);
 
        numbers[i++] = new TelephoneNumber(firstname+" "+lastname, number);
      }
    } catch(Exception ex) {
      ex.printStackTrace();
    }
    for(TelephoneNumber telephoneNumber : numbers) {
      System.out.println(telephoneNumber);
    }
  }
}

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

Scanner sc = new Scanner(new File("telephone-list.txt"));

με την γραμμή

Scanner sc = new Scanner(System.in);

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

Εκτός από διάβασμα αρχείων κειμένου όπως αυτά που είδαμε παραπάνω ή διάβασμα από την κονσόλα υπάρχει η πιθανόντητα να θέλετε να διαβάσετε δυαδικά αρχεία. Τα δυαδικά αρχεία περιέχουν πληροφορία η οποία δεν μπορεί να κωδικοποιηθεί σε χαρακτήρες. Παραδείγματα δυαδικών αρχείων είναι μία εικόνα (jpg, png κλπ), ένα video (οποιουδήποτε format), ένα αρχείο pdf, ένα αρχείο MSWord, MSExcel κ.α. Σε αυτές τις περιπτώσεις το διάβασμα της πληροφορίας με τις κλάσεις που παρουσιάσαμε προηγούμενα δεν είναι δυνατόν να υλοποιηθεί.

Αντ' αυτού υπάρχει η κλάση java.io.FileInputStream η οποία επιτρέπει το διάβασμα δυαδικών αρχείων ως εξής:

Κατασκευαστές

Μέθοδοι

Παράδειγμα διαβάσματος από δυαδικό αρχείο

Το παρακάτω πρόγραμμα διαβάζει το όνομα ενός αρχείου από το πληκτρολόγιο και στη συνέχεια διαβάζει το περιεχόμενο του αρχείου ως δυαδικό αρχείο.

ReadBinFile.java
import java.io.*;
import java.util.*;
 
public class ReadBinFile {
  public static void main(String [] args) {
 
    Scanner sc = new Scanner(System.in);
    System.out.print("Enter filename: ");
    String readFilename = sc.next();
    File readFile = new File(readFilename);    
 
    if( !readFile.isFile() ) {
      System.err.println("Input file does not exist or is not a regular file!");
      return;
    }
    if( !readFile.canRead() ) {
      System.err.println("Input file is not readable!");
      return;
    }
 
    try {
      byte []buffer = new byte[2048];
      FileInputStream in = new FileInputStream(readFile);
      int read_len;
      while( (read_len = in.read(buffer)) != -1 ) {
 
      }
 
      in.close();
    } catch( IOException ex ) {
      ex.printStackTrace();
    }
  }
}