Näkyvyysalueet
Näkyvyydensäätelymääreillä public, private ja protected säädellään luokkien, kenttien, konstruktoreiden ja metodien näkyvyyttä (metodien ja konstruktoreiden paikalliset muuttujat eivät näy niiden ulkopuolelle):
public: näkyy "koko maailmassa"
private: näkyy vain samassa luokassa, ei edes aliluokissa
protected: voi näkyä sekä aliluokassa että omassa pakkauksessa
ei määrettä (oletusnäkyvyys): voi näkyä omassa pakkauksessa
Esimerkiksi luokalla, kentällä ja metodilla voi olla sama nimi. Kääntäjä käyttää hyväksi nimen käyttöyhteyttä nimen merkityksen ymmärtämiseen.
Nimien merkityksen etsintäjärjestys
metodin paikalliset nimet (myös muodolliset parametrit)
oman luokan nimet (myös luokan perimät nimet)
eksplisiittisesti tuodut luokat
(import pakkaus.Luokka)
omasssa pakkauksessa näkyvät luokat (muut kuin private-määreellä varustetut pakkauksen luokat)
implisiittisesti tuodut luokat (import pakkaus.*)
automaattisesti tuodut luokat (java.lang ja mahdolliset muut toteutuksen tarjoamat valmiit apuvälineet)
Jos esimerkiksi konstruktorin parametrilla on sama nimi kuin luokan kentällä, pitää kenttään viitatessa käyttää ilmausta this:
class Opiskelija {
String nimi;
public Opiskelija(String nimi) {
this.nimi = nimi;
}
...
}
Poikkeukset
Ohjelman suorituksen aikana törmätään usein virhetilanteisiin esimerkiksi siksi, että käyttäjän antama syöte ei ollut odotetunlainen tai siksi, että ohjelmassa on virhe.
Esimerkki: ohjelma pyytää käyttäjältä kokonaislukua, mutta käyttäjä antaa merkkijonon 2r5
Java tarjoaa välineitä tällaisten virhetilanteiden, poikkeusten, käsittelyyn.
Poikkeukset on toteutettu luokkina. Kaikkien poikkeusten yliluokka on Execption. Kaikki mahdolliset poikkeukset ovat siis luokan Execption olioita.
Erilaisia poikkeuksia varten on omia aliluokkia, esimerkiksi ArithmeticException, ArrayIndexOutOfBoundsException, ClassNotFoundException, NumberFormatException, FileNotFoundException.
Ohjelmassa on mahdollisuus tutkia, minkä luokan poikkeus on aiheutunut ja sen mukaan mahdollisuus päätellä, mikä on aiheuttanut ongelman. Ohjelmoija voi määritellä myös omia poikkeuksiaan.
Poikkeukset jaetaan kahteen luokkaan:
checked exceptions - kääntäjä vaatii, että näiden poikkeusten ilmaantumiseen on ohjelmassa varauduttu.
unchecked exception - kääntäjä ei vaadi tällaisiin poikkeuksiin varautumista, mutta niiden ilmaantuminen kaataa ohjelman, jos niihin ei ole varauduttu.
Poikkeusten käsittely
Jos joku metodin suorituksessa aiheuttaa poikkeuksen, niin se voidaan käsitellä kahdella eri tavalla:
Siepataan poikkeus ja käsitellään sen aiheuttama virhetilanne. Jos esimerkiksi ohjelma pyytää kokonaislukua, mutta käyttäjä antaa kelvottoman merkkijonon, pyydetään käyttäjältä parempi luku. Tämä voidaan tehdä try-catch-rakenteella.
Heitetään poikkeus kutsuvalle metodille. Kutsuva metodi voi joko heittää poikkeuksen edelleen sitä kutsuvalle metodille tai käsitellä poikkeuksen aiheuttaneen virhetilanteen. Poikkeus voidaan heittää
throws-ilmaisulla. Jos pääohjelma heittää poikkeuksen, koko ohjelma kaatuu.
Poikkeuksen heittäminen
Laaditaan ohjelma, joka laskee ja tulostaa komentoriviparametrina annetun liukuluvun neliöjuuren.
Komentoriviparametrit ovat aina merkkijonoja. Neliöjuuren laskemista varten merkkijono pitää muuttaa desimaaliluvuksi.
Luokasta Double löytyy konstruktori Double(), jolle voi antaa parametrina merkkijonon. Konstruktori muodostaa parametrimerkkijonoa vastaavan Double-olion. Olion sisältämän desimaaliluvun arvon saa selville metodilla doubleValue().
luku = new Double(args[0]).doubleValue();
juuri = Math.sqrt(luku);
Konstruktori Double voi kuitenkin aiheuttaa NumberFormatException-luokan poikkeuksen, jos parametrina annetusta merkkijonosta ei voi muodostaa liukulukua.
NumberFormatException on tarkistettava poikkeus. Konstruktoria kutsuvassa metodissa on joko käsiteltävä mahdollinen poikkeus tai heitettävä poikkeus eteenpäin.
Metodin otsikossa oleva ilmaus throws Exception kertoo, että tämä metodi voi heittää poikkeuksen.
public class Neliojuuri {
public static void main(String[] args)
throws Exception {
double luku, juuri;
luku = new Double(args[0]).doubleValue();
juuri = Math.sqrt(luku);
System.out.println(juuri);
}
}
Kun ohjelmaa ajetaan erilaisilla komentoriviparametreilla, saadaan seuraavia tulostuksia:
> java Neliojuuri 16.0
4.0
> java Neliojuuri 4.0r5
java.lang.NumberFormatException: 4.0r5
at java.lang.Double.<init>(Compiled
Code)
at Neliojuuri.main(Compiled Code)
> java Neliojuuri mita
java.lang.NumberFormatException: mita
at java.lang.Double.<init>(Compiled
Code)
at Neliojuuri.main(Compiled Code)
> java Neliojuuri
java.lang.ArrayIndexOutOfBoundsException: 0
at Neliojuuri.main(Compiled Code)
> java Neliojuuri 4.0e2
20.0
Tämä ei kuitenkaan ole hyvää ohjelmointityyliä. Sen sijaan on hyväksyttävää heittää poikkeus jostain metodista ja käsitellä se metodia kutsuvassa metodissa (esimerkkejä myöhemmin)
Poikkeuksen sieppaaminen
Toinen vaihtoehto poikkeuksen käsittelyyn on siepata poikkeus ja käsitellä jotenkin sen aihettanut virhetilanne.
Poikkeus siepataan try-catch-lauseella:
try {
... yritetään jotain, joka voi aiheuttaa
poikkeuksen Poikkeuksen_tyyppi.
Jos poikkeusta ei aiheuteta, try-osa
suoritetaan loppuun ja jätetään
catch-osa väliin
}
catch (Poikkeuksen_tyyppi poikkeuksen_nimi) {
... käsitellään siepattu poikkeus, jos
try-osa aiheutti poikkeuksen
Poikkeuksen_tyyppi.
}
Lauseen suoritus aloitetaan suorittamalla try-osassa olevia käskyjä normaalissa järjestyksessä.
Jos mikä tahansa try-osan käsky aiheuttaa poikkeuksen, jonka tyyppi on Poikkeuksen_tyyppi, siirrytään heti catch-osan suoritukseen.
Jos mikään try-osan suoritus ei aiheuta Poikkeuksen_tyyppi-tyyppistä poikkeusta, hypätään try-osan suorituksen jälkeen catch-osan yli.
catch-osia voi olla useita erityyppisille poikkeuksille. Tällöin suoritettava catch-osa valitaan tapahtuneen poikkeuksen tyypin mukaan.
Neliöjuuren laskeva ohjelma uudelleen:
public class Neliojuuri2 {
public static void main(String[] args) {
double luku, juuri;
try {
luku = new Double(args[0]).doubleValue();
juuri = Math.sqrt(luku);
System.out.println(juuri);
} catch (NumberFormatException e) {
System.out.println("Parametria ei voi tulkita luvuksi");
}
}
}
Nyt ohjelman ajaminen eri parametreilla tulostaa seuraavaa:
> java Neliojuuri2 16.0
4.0
> java Neliojuuri2 4.0r5
Parametria ei voi tulkita luvuksi
> java Neliojuuri2 mita
Parametria ei voi tulkita luvuksi
> java Neliojuuri2
java.lang.ArrayIndexOutOfBoundsException: 0
at Neliojuuri2.main(Compiled Code)
> java Neliojuuri2 4.0e2
20.0
Edellinen ohjelma kaatui, jos sille ei antanut komentoriviparametria. Muutetaan ohjelmaa siten, että se käsittelee myös komentoriviparametrin puuttumisesta aiheutuvan poikkeuksen:
public class Neliojuuri3 {
public static void main(String[] args) {
double luku, juuri;
try {
luku = new Double(args[0]).doubleValue();
juuri = Math.sqrt(luku);
System.out.println(juuri);
} catch (NumberFormatException e1) {
System.out.println("Parametria ei voi tulkita luvuksi");
} catch (ArrayIndexOutOfBoundsException e2) {
System.out.println("Parametri puuttuu");
}
}
}
Ohjelman tulostusta eri parametreilla:
> java Neliojuuri3 16.0
4.0
> java Neliojuuri3 4.0r5
Parametria ei voi tulkita luvuksi
> java Neliojuuri3 mita
Parametria ei voi tulkita luvuksi
> java Neliojuuri3
Parametri puuttuu
> java Neliojuuri3 4.0e2
20.0
Seuraava ohjelma sieppaa minkä tahansa poikkeuksen
public class Neliojuuri4 {
public static void main(String[] args) {
double luku, juuri;
try {
luku = new Double(args[0]).doubleValue();
juuri = Math.sqrt(luku);
System.out.println(juuri);
} catch (NumberFormatException e1) {
System.out.println("Parametria ei voi tulkita luvuksi");
} catch (ArrayIndexOutOfBoundsException e2) {
System.out.println("Parametri puuttuu");
}
}
}
Ohjelman tulostusta:
> java Neliojuuri4 16.0
4.0
> java Neliojuuri4 4.0r5
Lasku ei onnistu!
> java Neliojuuri4 mita
Lasku ei onnistu!
> java Neliojuuri4
Lasku ei onnistu!
> java Neliojuuri4 4.0e2
20.0
Seuraavassa ohjelmassa metodi heittää poikkeuksen, joka käsitellään pääohjelmassa (kutsuvassa metodissa):
public class Neliojuuri5 {
private static double laskeJuuri(String lukumjono)
throws Exception {
double luku, juuri;
luku = new Double(lukumjono).doubleValue();
juuri = Math.sqrt(luku);
return juuri;
}
public static void main(String[] args) {
double juuri;
try {
if (args.length >= 1) {
juuri = laskeJuuri(args[0]);
System.out.println(juuri);
}
else
System.out.println("Parametri puuttuu!");
} catch (Exception e) {
System.out.println("Lasku ei onnistu!");
}
}
}
Poikkeuksen aiheuttaminen
Ohjelmoija voi itse aiheuttaa poikkeuksen throw-käskyllä. Sillä aliohjelman suorituksen voi katkaista sellaisesta kohdasta, jossa virhe tapahtui.
Aiheutettava poikkeus luodaan Exception-luokan tai sen aliluokan konstruktorilla.
Luotavaan poikkeukseen voi liittää poikkeuksesta kertovan viestin, johon pääsee muualta käsiksi Exception-luokan getMessage-metodilla.
Esimerkki: aiheutetaan poikkeus, johon liittyy viesti "Liian pieni exp":
if (exp <= 0)
throw new Exception("Liian pieni exp");
Seuraava esimerkkiohjelma tutkii, riittääkö koepistemäärä kokeen läpäisyyn. Koe on läpäisty, jos on saatu vähintään puolet maksimipisteistä. Jos pisteitä on yli maksimipistemäärän tai alle nollan, aiheutetaan poikkeus.
public class PoikkeusPisteet {
private static boolean lapaisy(int maxPisteet, int koePisteet)
throws Exception {
boolean tulos = false;
if (koePisteet > maxPisteet)
throw new Exception("Koepisteet yli maksimirajan");
else if (koePisteet < 0)
throw new Exception("Koepisteet alle nollan");
else if (1.0 * koePisteet / maxPisteet > 0.5)
tulos = true;
return tulos;
}
public static void main(String[] args) {
try {
if (lapaisy(30, 14))
System.out.println("Eka läpi!");
else
System.out.println("Eka hylsy!");
if (lapaisy(30, 35))
System.out.println("Tok läpi!");
else
System.out.println("Toka hylsy!");
} catch (Exception e) {
System.out.println("Poikkeus: " +
e.getMessage());
}
}
}
Syötteen lukeminen
Tähän asti käyttäjän antamaa syötettä on luettu Lue-luokan avulla. Nyt opitaan, miten syötettä luetaan Javan perusvälineillä.
Java 1.0 tarjosi mm. luokan InputStream syötteen lukemista varten. Luokan tarjoamilla metodeilla lukeminen oli kuitenkin hankalaa, koska syötettä pystyttiin lukemaan vain tavuittain.
Java 1.1 tarjoaa luokan BufferedReader syötteen lukemiseen. BufferedReader sisältää mm. metodin readLine(), jolla voidaan lukea yksi rivi syötteestä.
Jotta syötettä voitaisiin lukea, pitää ensin muodostaa BufferedReader-luokan olio. Olion luonnin yhteydessä kerrotaan, mistä syötettä luetaan - standardisyöttövirrasta (yleensä näppäimistö) vai jostain tiedostosta.
Luokassa System on määritelty standardisyöttövirta kenttänä in:
public static final InputStream in;
InputStream-oliota ei voi kuitenkaan antaa suoraan paramteriksi BufferedReader-luokan konstruktorille, vaan pitää ensin luoda sen avulla InputStreamReader-olio, joka annetaan parametriksi.
BufferedReader-luokan olio, jonka avulla voidaan lukea syötettä standarisyöttövirrasta, voidaan nyt luoda seuraavasti:
BufferedReader stdin;
stdin = new BufferedReader(new
InputStreamReader(System.in));
Tämän jälkeen syötettä voidaan lukea rivi kerrallaan String-olioon:
String mjono;
mjono = stdin.readLine();
Luettu rivi on nyt merkkijonomuodossa. Jos kuitenkin haluttiin lukea kokonaisluku, merkkijono on muutettava kokonaisluvuksi:
int i;
i = Integer.parseInt(mjono);
Jos merkkijono ei kelpaa kokonaisluvuksi, aiheutuu poikkeus NumberFormatException.
Jos haluttiin lukea desimaaliluku, on merkkijono muutettava liukuluvuksi (myös tämä voi aiheuttaa poikkeuksen):
double d;
d = new Double(mjono).doubleValue();
Lukeminen tiedostosta tehdään muuten samaan tapaan, mutta InputStreamReader-luokan konstruktorille annetaan erilainen parametri.
Seuraavassa esitetään joitain esimerkkiohjelmia arvojen lukemisesta. Huomattavia asioita:
Tietojen lukemiseen liittyvät poikkeukset ovat tarkistettavia poikkeuksia. Ohjelmoijan on otettava niiden mahdollisuus huomioon joko sieppaamalla poikkeus (try-catch) tai ilmoittamalla, että poikkeus voi tulla (throws)
Tiedostonkäsittelyluokat (esim. BufferedReader) tuodaan ohjelman käyttöön ilmauksella
import java.io.*;
Jos halutaan tulostaa jotain ilman rivinvaihtoa System.out.print-metodilla, on tulostuspuskuri tyhjennettävä tulostustiedostoon (esimerkeissä kuvaruudulle) käskyllä System.out.flush(), jotta teksti ilmestyisi kuvaruudulle ennen ohjelman seuraavan käskyn suorittamista.
Poikkeuksilla on oma toString-metodinsa, joten ne voidaan tulostaa poikkeukseen viittavan muuttujan nimeä käyttämällä.
Jos ohjelma pyytää käyttäjältä uutta syötettä, kunnes se saa kelvollisen syötteen, on varauduttava myös tiedoston loppumiseen.
import java.io.*;
public class PoikkeusKokeita {
public static void main(String[] args) {
BufferedReader stdin =
new BufferedReader(new InputStreamReader(System.in));
String jono = null;
int kluku;
double dluku;
boolean ok;
try {
System.out.print("Anna kokonaisluku: ");
System.out.flush();
jono = stdin.readLine();
kluku = Integer.parseInt(jono);
System.out.println("Se oli: "+kluku);
} catch (Exception e) {
System.out.println("Virhe: " + e);
}
do {
try {
System.out.print("Anna desimaaliluku: ");
System.out.flush();
jono = stdin.readLine();
dluku = new Double(jono).doubleValue();
System.out.println("Se oli: "+dluku);
ok = true;
} catch (Exception e) {
System.out.println("Virhe :" + e);
ok = false;
}
} while (!ok && jono != null);
}
}
import java.io.*;
public class PoikkeusKokeita2 {
public static void main(String[] args) {
BufferedReader stdin =
new BufferedReader(new InputStreamReader(System.in));
String jono = null;
double dluku;
boolean loppu = false;
do {
try {
System.out.print("Anna desimaaliluku: ");
System.out.flush();
jono = stdin.readLine();
dluku = new Double(jono).doubleValue();
System.out.println("Se oli: "+dluku);
loppu = true;
} catch (NumberFormatException e) {
System.out.println("Virhe: ei ole luku");
} catch (NullPointerException e) {
System.out.println("Virhe: tiedosto loppui");
loppu = true;
} catch (IOException e) {
System.out.println("Virhe: ongelma tiedostossa");
loppu = true;
}
} while (!loppu);
}
}
import java.io.*;
public class PieniSuuri {
public static void main(String[] args) {
BufferedReader stdin =
new BufferedReader(new InputStreamReader(System.in));
int i;
boolean loppu = false;
String mjono;
char[] taulu;
System.out.println("Pienet suuriksi ja suuret pieniksi, "+
"lopeta ctrl-d:llä");
while (!loppu) {
try {
System.out.print("Anna muutettava: ");
System.out.flush();
mjono = stdin.readLine();
taulu = mjono.toCharArray();
for (i=0; i
Tekstitiedostosta
lukeminen
Tähän
asti ohjelmat ovat lukeneet syötteensä aina
standardisyöttövirrasta. Se on yleensä näppäimistö,
mutta käyttöjärjestelmän puolella voidaan
standarisyöttövirta yhdistää myös
tiedostoon, esimerkiksi käynnistämällä ohjelma
Prog käskyllä
>
java Prog <teksti.txt
saadaan
ohjelma lukemaan syötteensä näppäimistön
sijasta tiedostosta teksti.txt.
Tällä
tavalla ohjelma voi kuitenkin lukea vain yhdestä tiedostosta
ajonsa aikana. Lisäksi sama ohjelma ei voi lukea tietoja sekä
näppäimistöltä että tiedostosta.
BufferedReader-luokan
avulla ohjelma voi lukea tietoja monesta tiedostosta ajonsa aikana.
Lukeminen tapahtuu samaan tapaan kuin standarisyöttövirrasta
lukeminen. Ero on BufferedReader-luokan
konstruktorin parametrissa.
BufferedReader-olion
avulla voi lukea syötettä tiedostosta "juttu.txt"
esimerkiksi luomalla olion seuraavasti:
BufferedReader
syotto =
new
BufferedReader(
new
InputStreamReader(
new
FileInputStream("juttu.txt")));
Tämän
jälkeen tiedostosta voi lukea rivin kerrallaan String-tyyppiseen
muuttujaan rivi:
rivi
= syotto.readLine();
Seuraava
ohjelma lukee tiedoston "juttu.txt" rivi kerrallaan ja
tulostaa rivit kuvaruudulle:
import java.io.*;
public class Listaa {
public static void main(String[] args) {
String rivi;
try {
BufferedReader syotto =
new BufferedReader(new InputStreamReader(new
FileInputStream("juttu.txt")));
while((rivi = syotto.readLine()) != null)
System.out.println(rivi);
} catch (IOException e) {
System.out.println("Virhe tiedoston lukemisessa");
}
}
}
Ohjelmassa
on kuitenkin joitakin puutteita:
se
osaa lukea vain tiedostoa, jonka nimi on juttu.txt
se
ei pysty mitenkään muuten käsittelemään
tiedostoa, esimerkiksi ilmoittamaan, onko tiedostoa olemassa.
Puutteita
voi korjata ottamalla käyttöön luokan File.
File-luokan
avulla voidaan luoda olio, jonka avulla voidaan tutkia tiedoston
olemassaoloa ja tehdä muita tiedostoille tyypillisiä
asioita.
Luokka File
Luokan
File avulla voi
hallinnoida tiedostoja. Luokan avulla voi esimerkkiksi selvittää,
onko tiedosto olemassa, mikä sen pituus on sekä
uudelleennimetä ja poistaa tiedostoja.
Luokalla
on mm. konstruktori
public
File(String path)
jolle
annetaan parametrina käsiteltävän tiedoston nimi
mahdollisine hakemistopolkuineen.
Tärkeimpiä
File-luokan metodeita
boolean
exists() palauttaa arvon true,
jos tiedosto on olemassa
long
length() palauttaa tiedoston pituuden
boolean
renameTo(File dest) nimeää tiedoston uudelleen,
palauttaa arvon true,
jos onnistui
boolean
delete() tuhoaa tiedoston, palauttaa arvon true,
jos tuhoaminen onnistui
String
getName() palauttaa tiedoston nimen
Esimerkkiohjelma
vaihtaa tiedoston juttu.txt nimeksi uusinimi.txt:
import java.io.*;
public class Tiedostot {
public static void main(String[] args) {
File vanha, uusi;
vanha = new File("juttu.txt");
uusi = new File("uusinimi.txt");
if (!uusi.exists())
vanha.renameTo(uusi);
else
System.out.println("Tiedosto uusinimi.txt on jo olemassa");
}
}
Ohjelma
on aika kankea, koska tiedostojen nimet ovat vakioita.
Seuraava
ohjelma saa tiedostojen nimet komentoriviparametreina:
import java.io.*;
public class Tiedostot2 {
public static void main(String[] args) {
File vanha, uusi;
if (args.length != 2)
System.out.println("Väärä määrä parametreja!");
else {
vanha = new File(args[0]);
uusi = new File(args[1]);
if (!uusi.exists())
vanha.renameTo(uusi);
else
System.out.println("Tiedosto " + args[1] + " on jo olemassa");
}
}
}
File-luokan
käyttö tiedostojen lukemisessa
Esimerkkiohjelma
tulostaa tiedoston kuvaruudulle. Tiedoston nimi annetaan
komentoriviparametrina.
import java.io.*;
public class Listaa2 {
public static void main(String[] args) {
File syoTd;
BufferedReader syotto;
String rivi;
if (args.length != 1)
System.out.println("Väärä määrä parametreja");
else {
syoTd = new File(args[0]);
if (!syoTd.exists())
System.out.println("Tiedostoa "
+ args[0] + " ei löydy");
else
try {
syotto = new BufferedReader(
new InputStreamReader(
new FileInputStream(syoTd)));
while ((rivi = syotto.readLine()) != null)
System.out.println(rivi);
} catch (IOException e) {
System.out.println("Virhe tiedoston lukemisessa");
}
}
}
}
Seuraava
ohjelma pyytää tulostettavan tiedoston nimen käyttäjältä.
Nyt tarvitaan kaksi BufferedReader-oliota:
toinen tiedoston lukemiseen ja toinen käyttäjän
syötteen lukemiseen.
import java.io.*;
public class Listaa3 {
public static void main(String[] args) {
File syoTd;
BufferedReader stdin, tdsto;
String nimi, rivi;
try {
stdin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Minkä tiedoston haluat nähdä?");
nimi = stdin.readLine();
syoTd = new File(nimi);
if (!syoTd.exists())
System.out.println("Tiedostoa "
+ nimi + " ei löydy");
else {
tdsto = new BufferedReader(
new InputStreamReader(
new FileInputStream(syoTd)));
while ((rivi = tdsto.readLine()) != null)
System.out.println(rivi);
}
} catch (Exception e) {
System.out.println("Virhe syotteen tai tiedoston lukemisessa");
}
}
}
Tekstitiedoston
kirjoittaminen
Luokan
PrintWriter olioiden
avulla voidaan tulostaa tekstitiedostoon print-
ja println-metodeilla
samaan tyyliin kuin kuvaruudulle.
Luokan
ilmentymiä (tulostiedostoja) voidaan luoda konstruktorilla
PrintWriter(OutputStream
out,
boolean autoFlush)
Jälkimmäinen
parametri ohjaa tulostuspuskurin tiedojen siirtämistä
varsinaiseen tiedostoon. Kun parametri asetetaan trueksi,
tiedostoa ei tarvitse itse sulkea ohjelman lopussa.
Ensimmäisen
parametrin avulla tulostus ohjataan haluttuun tiedostoon.
Parametriksi ei voi kuitenkaan antaa suoraan tiedoston nimeä tai
File-oliota. Sen sijaan
parametriksi voi antaa FileOutputStream-olion,
jonka voi luoda jollakin konstruktoreista
FileOutputStream(String
name)
FileOutputStream(String
name, boolean append)
FileOutputStream(File
file)
Kahden
ensimmäisen parametrina on tiedoston nimi, kolmannen File-olio.
Toisen konstruktorin avulla voi tulostaa olemassa olevan tiedoston
loppuun antamalla parametrin append
arvoksi true.
Tiedostoon
voi tulostaa rivin esimerkiksi seuraavasti
PrintWriter
tulos =
new
PrintWriter(
new
FileOutputStream("tulos.txt"),
true);
...
tulos.println("Hip
hei!");
tulos.println("Toinen
rivi");
Jos
tiedosto tulos.txt oli jo olemassa, sen vanha sisältö
häviää. Seuraava esimerkki tulostaa tiedoston
juttu.txt loppuun (tiedoston vanha sisältö säilyy)
PrintWriter
juttu =
new
PrintWriter(
new
FileOutputStream("tulos.txt", true),
true);
...
juttu.println("Rivi
loppuun");
juttu.println("Toinen
rivi loppuun");
Seuraava
ohjelma kirjoittaa käyttäjän antamat rivit tiedostoon
juttu.txt. Käyttäjä voi lopettaa rivien antamisen
tiedoston loppu -merkillä (UNIXissa ctrl-d).
import java.io.*;
public class Talleta1 {
public static void main(String[] args) {
PrintWriter tdsto;
BufferedReader stdin;
String rivi;
try {
tdsto = new PrintWriter(new FileOutputStream("juttu.txt"),
true);
stdin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Kirjoitetaan tiedostoon juttu.txt");
while ((rivi = stdin.readLine()) != null)
tdsto.println(rivi);
} catch (Exception e) {
System.out.println("Virhe lukemisessa tai kirjoittamisessa");
}
System.out.println("Kiitos!");
}
}