6. Tiedostot 6.1
Sisältö Johdanto. Tiedostojen lukeminen. Tiedostojen kirjoittaminen. 6.2
Johdanto Tiedostoja on käsitelty uudelleenohjattujen standardisyöte- ja tulostusvirtojen avulla. Tiedostoja voidaan käyttää myös ohjelmasta käsin. Tutustutaan tekstitiedostojen lukemiseen ja kirjoittamiseen java.io-pakkauksen luokkien avulla. Javan versiosta 1.5 alkaen käytettävissä myös java.utilpakkauksen Scanner- ja Formatter-luokat. import java.io.*; (tai import java.util.*;). Lukeminen ja kirjoittaminen tapahtuu vaiheittain: avataan, luetaan tai kirjoitetaan, suljetaan. 6.3
Avaaminen lukemista varten Tiedoston avaaminen tarkoittaa yleisesti syötevirran liittämistä tiedostosta ohjelmaan. Javassa syötevirta avataan esimerkiksi luomalla FileInputStream-luokan olio. Yleisesti: FileInputStream olionnimi = new FileInputStream(tiedostonNimi); Esimerkiksi: FileInputStream syotevirrannimi = new FileInputStream( in.txt ); 6.4
Lukeminen Syötevirrasta lukemiseen tarvitaan olio InputStreamReader-luokasta. Esimerkiksi: InputStreamReader lukijannimi = new InputStreamReader(syotevirranNimi); Usein on kätevämpää käyttää hienostuneempaa lukijaa. Tällaisen tarjoaa BufferedReader-luokka. Esimerkiksi: BufferedReader puskuroitulukija = new BufferedReader(lukijanNimi); 6.5
Lukeminen Kun syötevirtaan on saatu liitettyä BufferedReaderlukija, voidaan tekstitiedostoa lukea riveittäin readline-operaation avulla. Ready-operaatio kertoo voidaanko lukea uusi rivi. Esimerkiksi: while (puskuroitulukija.ready()) { String rivi = puskuroitulukija.readline(); System.out.println(rivi); 6.6
Rivien käsittely Usein yhdellä rivillä on useampia jollakin merkillä (esimerkiksi pilkku tai välilyönti) erotettuja tietoja, jotka voivat vieläpä olla eri tyyppisiä. String-luokan split-operaatio on tässä tilanteessa hyödyllinen se pilkkoo rivi osiinsa. Esimerkiksi: String rivi = "this is a test"; String[] osat = rivi.split("[ ]"); for (int i = 0; i < osat.length; i++) System.out.println(osat[i]); 6.7
Sulkeminen lukemisen jälkeen Tiedoston lukemisen jälkeen siihen liitetty syötevirta suljetaan close-operaatiolla. Esimerkiksi: puskuroitulukija.close(); Tiedoston avaamisen, lukemisen ja/tai sulkemisen yhteydessä voi tapahtua poikkeus. Tämän vuoksi Java pakottaa sulkemaan useimmat tiedostonkäsittelyyn liittyvät lauseet try-catchlauseen sisään. 6.8
Esimerkki import java.io.*; while (puskuroitulukija.ready()) { public class Lukeminen1 { String rivi = puskuroitulukija.readline(); public static void main(string[] args) { System.out.println(rivi); String TIEDNIMI = "in.txt"; try { puskuroitulukija.close(); FileInputStream syotevirta = new FileInputStream(TIEDNIMI); catch (FileNotFoundException e) { InputStreamReader lukija = System.out.print("Tiedosto hukassa!"); new InputStreamReader(syotevirta); BufferedReader puskuroitulukija = catch (Exception e) { new BufferedReader(lukija); System.out.print("Lukuvirhe!"); 6.9
Esimerkki import java.io.*; import java.util.*; public class Lukeminen2 { public static void main(string[] args) { String TIEDNIMI = "in.txt"; try { // Luodaan tiedosto-olio. File tiedosto = new File(TIEDNIMI); // Luodaan lukija. Scanner lukija = new Scanner(tiedosto); // Luetaan ja tulostetaan rivit. while (lukija.hasnextline()) { String rivi = lukija.nextline(); System.out.println(rivi); // Suljetaan lukija. lukija.close(); catch (FileNotFoundException e) { System.out.print("Tiedosto hukassa!"); catch (Exception e) { System.out.print("Lukuvirhe!"); 6.10
Avaaminen kirjoittamista varten 1) Luodaan tiedosto-olio File-luokasta: File tiedostoolionnimi = new File(tiedostonNimi); 2) Liitetään tulostusvirta ohjelmasta tiedostoon: FileOutputStream virtaolionnimi = new FileOutputStream(tiedostoOlionNimi); 6.11
Kirjoittaminen Tulostusvirtaan kirjoittamiseen tarvitaan kirjoittajaolio PrintWriter-luokasta. Yleisesti: PrintWriter kirjoittajaolionnimi = new PrintWriter(virtaOlionNimi, true); Kirjoittaminen tapahtuu PrintWriter-luokan print- ja println-operaatioiden avulla. Nämä operaatiot on kuormitettu kuten System.outattribuutin kautta kutsuttavat operaatiot, jotka tulostavat esimerkiksi lukuja ja merkkijonoja. 6.12
Sulkeminen kirjoittamisen jälkeen Tiedoston kirjoittamisen jälkeen siihen liitetty syötevirta suljetaan kirjoittajan close-operaatiolla. Myös kirjoittamisen yhteydessä voi tapahtua poikkeus: tarvitaan poikkeuksen käsittelyä trycatch-lauseen avulla. 6.13
Tiedostot: esimerkki import java.io.*; public class Kirjoittaminen { public static void main(string [] args) { final String TIEDNIMI = "out.txt"; final int HEIPPALKM = 10; try { // Luodaan tiedosto-olio File tiedosto = new File(TIEDNIMI); // Luodaan tulostusvirta ja // liitetään se tiedostoon FileOutputStream tulostusvirta = new FileOutputStream(tiedosto); // Luodaan virtaan kirjoittaja PrintWriter kirjoittaja = new PrintWriter(tulostusvirta, true); // Kirjoitetaan tiedostoon for (int i = 0; i < HEIPPALKM; i++) kirjoittaja.println("heippa " + i); // Suljetaan tiedosto kirjoittaja.close(); catch (IOException e) { System.out.println(e); 6.14