Kapitel 15. Datastrømme og filhåndtering

Indhold:

Kapitlet forudsættes af Kapitel 16, Netværkskommunikation og Kapitel 18, Serialisering.

Forudsætter Kapitel 14, Undtagelser.

En fil er et arkiv på et lagermedium, hvori der er gemt data. På lagermediet gemmes en række 0'er og 1-taller (bit) i grupper a 8 bit, svarende til en byte (et tal mellem 0 og 255).

Data kan være gemt binært, sådan at de kun kan læses af et program eller styresystemet. Det gælder f.eks. en .exe-fil eller et dokument gemt i et proprietært binært format som f.eks. Word. De kan også være gemt som tekst uden formatering. Det gælder f.eks. filer, der ender på .txt, .html og .java. Oplysningerne i tekstfiler kan læses med en teksteditor. Det er op til programmet, der læser/skriver i filen, at afgøre, om indholdet er tekst eller binært.

I Java behandles filer som datastrømme. En datastrøm er et objekt, som man enten henter data fra (læser fra en datakilde, f.eks. en fil) eller skriver data til (et datamål).

Denne arbejdsmåde gør, at forskellige datakilder og -mål kan behandles ensartet, og at det er let at udskifte datakilden eller -målet med noget andet end en fil, f.eks. en forbindelse til netværket.

15.1. Skrive til en tekstfil

Klassen FileWriter bruges til at skrive en fil med tekstdata. I konstruktøren angiver man filnavnet:

    FileWriter fil = new FileWriter("tekstfil.txt");

FileWriter-objektet er en datastrøm, hvis mål er filen. Nu kan man skrive tekstdata til filen med:

    fil.write("Her kommer et tal:\n");
    fil.write(322+"\n");

FileWriter-objektets write()-metode er lidt besværlig at arbejde med, da den ikke understøtter linjeskift (som så i stedet må laves med "\n").

Figur 15-1. Java

Det er mere bekvemt at lægge objektet ind i en PrintWriter. Et PrintWriter-objekt har print() og println()-metoder, som vi er vant til, og man skal skrive til den præcis, som når man skriver til System.out:

    PrintWriter ud = new PrintWriter(fil);
    ud.println("Her kommer et tal:");
    ud.println(322);

Når vi skriver til PrintWriter-objektet, sender det teksten videre til FileWriter-objektet, der skriver teksten i filen.

Her er et samlet eksempel, der skriver nogle fiktive personers navn, køn og alder til en fil:

import java.io.*;
public class SkrivTekstfil 
{
  public static void main(String[] args) throws IOException
  {
    FileWriter fil = new FileWriter("skrevet fil.txt");
    PrintWriter ud = new PrintWriter(fil);
    for (int i=0; i<5; i++)
    {
      String navn = "person"+i;
      String køn;
      if (Math.random()>0.5) køn = "m"; else køn = "k";
      int alder = 10+(int) (Math.random()*60);

      ud.println(navn+" "+køn+" "+alder);
    }
    ud.close(); // luk så alle data skrives til disken
    System.out.println("Filen er gemt.");
  }
}

Resultatet bliver:

Filen er gemt.

Eventuelle IO-undtagelser (f.eks. ikke mere plads på disken) tager vi os ikke af, men sender dem videre til styresystemet.

Det er vigtigt at lukke filen, når man er færdig med at skrive. Ellers kan de sidste data gå tabt! Det gør man ved at lukke datastrømmen, man skrev til:

    ud.close();

Efter at programmet har kørt, findes filen "skrevet fil.txt" på disken, med indhold:

person0 m 34
person1 m 26
person2 m 24
person3 k 51
person4 k 16