Tiedostojen käyttäminen on tavallinen tapa tallentaa tietoa, jonka tulee säilyä muistissa ohjelman suorituskertojen välillä.
Tekstitiedosto muodostuu joukosta tekstirivejä. Seuraavassa on yksinkertainen tekstitiedosto, jossa on kolme riviä:
Tämä rivi aloittaa tiedoston. Sitten tulee toinen rivi. Kolmas rivi on jo viimeinen.
Tekstitiedostojen etuna on, että niitä on helppo käsitellä tavallisilla tekstieditoreilla ja eri ohjelmointikielissä. Kaikki tällä kurssilla käsiteltävät tiedostot ovat tekstitiedostoja.
Seuraava ohjelma lukee ja tulostaa tekstitiedoston sisällön:
import java.util.*; import java.io.*; public class TiedostostaLuku { public static void main(String[] args) throws Exception { Scanner tiedosto = new Scanner(new File("esimerkki.txt")); while (tiedosto.hasNextLine()) { String rivi = tiedosto.nextLine(); System.out.println(rivi); } } }
Ohjelman tulostus voi olla seuraava:
Tämä rivi aloittaa tiedoston. Sitten tulee toinen rivi. Kolmas rivi on jo viimeinen.
Kokeile, että saat ohjelman toimimaan omalla tiedostollasi. Tässä tiedoston
nimenä on esimerkki.txt
, ja tiedoston tulee olla
NetBeans-projektin päähakemistossa, jotta ohjelma löytää tiedoston.
Tiedoston lukeminen onnistuu Scanner
-olion kautta samaan tapaan
kuin käyttäjän kirjoittaman tekstin lukeminen, kunhan oliolle annetaan
tiedostoa vastaava File
-olio. Luokan File
käyttäminen
vaatii uuden import
-rivin koodin alkuun.
Lisäksi metodin main
loppuun on lisätty throws
Exception
, joka liittyy tiedostojen käsittelyssä mahdollisesti
tapahtuvien virheiden käsittelyyn. Palaamme tähän asiaan seuraavassa
luvussa.
Seuraava ohjelma tallentaa nimiä tiedostoon:
import java.io.*; import java.util.*; public class TiedostoonTallennus { public static void main(String[] args) throws Exception { PrintWriter tiedosto = new PrintWriter(new File("nimet.txt")); tiedosto.println("Aapeli"); tiedosto.println("Maija"); tiedosto.println("Uolevi"); tiedosto.close(); } }
Tämä ohjelma saa aikaan seuraavan tiedoston:
Aapeli Maija Uolevi
Tässä on käytössä PrintWriter
-olio, jonka avulla tiedostoon voi
tulostaa samaan tapaan kuin käyttäjän näytölle. Viimeinen komento
close
sulkee tiedoston. Älä unohda komentoa, koska muuten osa
riveistä saattaa jäädä puuttumaan tiedoston lopusta.
Huomaa, että jos tiedosto on olemassa valmiiksi, ohjelma korvaa tiedoston sisällön. Jos tiedostoa ei ole olemassa valmiiksi, ohjelma luo uuden tiedoston.
Tiedostossa sanalista.txt on Kotimaisten kielten tutkimuskeskuksen julkaisema nykysuomen sanalista.
Seuraava ohjelma etsii listalta kaikki palindromisanat eli sanat, joiden kirjaimet ovat samat alusta loppuun ja lopusta alkuun luettuna:
import java.util.*; import java.io.*; public class PalindromiSanat { public static boolean palindromi(String sana) { int pituus = sana.length(); for (int i = 0; i < pituus / 2; i++) { if (sana.charAt(i) != sana.charAt(pituus - i - 1)) { return false; } } return true; } public static void main(String[] args) throws Exception { Scanner tiedosto = new Scanner(new File("sanalista.txt")); while (tiedosto.hasNextLine()) { String sana = tiedosto.nextLine(); if (palindromi(sana)) { System.out.println(sana); } } } }
Ohjelman tulostus on seuraava:
ajaja akka ala alla autioitua ele enne hah heh huh hyh häh imaami isi niin oho olo opo otto piip pop sadas sammas sees siis sus suuruus sylys sytytys syys syöppöys tuut tyyt tööt utu yty älä ämmä ässä
Tiedostoformaatti tarkoittaa tapaa, jolla ohjelma tallentaa tietonsa tiedostoon. Tiedostoformaatti on ohjelmoijan päätettävissä, ja vaihtoehtoja on yleensä monia. Ainoa vaatimus on, että ohjelma tallentaa ja lukee tiedot samaa formaattia käyttäen.
Seuraavassa ohjelmassa käyttäjä voi lisätä tavaroita ostoslistalle sekä tallentaa ja ladata ostoslistan.
import java.util.*; import java.io.*; public class Ostoslista { private static Scanner input = new Scanner(System.in); private static String tiedostonNimi = "ostoslista.txt"; private static ArrayList<String> lista = new ArrayList<String>(); private static void lisaaListalle() { System.out.print("Tavaran nimi: "); String tavara = input.nextLine(); lista.add(tavara); } private static void tulostaLista() { System.out.println("Listan sisältö:"); for (String tavara : lista) { System.out.println(tavara); } } private static void tallennaLista() throws Exception { PrintWriter tiedosto = new PrintWriter(new File(tiedostonNimi)); int tavaramaara = lista.size(); tiedosto.println(tavaramaara); for (String tavara : lista) { tiedosto.println(tavara); } tiedosto.close(); } private static void lataaLista() throws Exception { Scanner tiedosto = new Scanner(new File(tiedostonNimi)); lista.clear(); int tavaramaara = Integer.parseInt(tiedosto.nextLine()); for (int i = 0; i < tavaramaara; i++) { String tavara = tiedosto.nextLine(); lista.add(tavara); } } public static void main(String[] args) throws Exception { System.out.println("1: Lisää tavara"); System.out.println("2: Tulosta lista"); System.out.println("3: Tallenna lista"); System.out.println("4: Lataa lista"); System.out.println("5: Sulje ohjelma"); while (true) { System.out.print("Anna komento: "); String komento = input.nextLine(); if (komento.equals("1")) { lisaaListalle(); } if (komento.equals("2")) { tulostaLista(); } if (komento.equals("3")) { tallennaLista(); } if (komento.equals("4")) { lataaLista(); } if (komento.equals("5")) { return; } } } }
Tässä tiedostoformaattina on, että tiedoston ensimmäisellä rivillä lukee tavaroiden määrä ja kullakin seuraavalla rivillä lukee yhden tavaran nimi.
Ohjelman ensimmäinen suorituskerta:
1: Lisää tavara 2: Tulosta lista 3: Tallenna lista 4: Lataa lista 5: Sulje ohjelma Anna komento: 1 Tavaran nimi: selleri Anna komento: 1 Tavaran nimi: retiisi Anna komento: 1 Tavaran nimi: nauris Anna komento: 2 Listan sisältö: selleri retiisi nauris Anna komento: 3 Anna komento: 5
Nyt tiedoston ostoslista.txt
sisältö on seuraava:
3 selleri retiisi nauris
Ohjelman toinen suorituskerta:
1: Lisää tavara 2: Tulosta lista 3: Tallenna lista 4: Lataa lista 5: Sulje ohjelma Anna komento: 4 Anna komento: 2 Listan sisältö: selleri retiisi nauris Anna komento: 5