2.11.2 Tiedoston avaaminen

Tekstitiedostoon kirjoittaminen tai sieltä lukeminen tapahtuu ihan samoin kuin näytölle tulostaminen tai näppäimistöltä lukeminen. Ainoana oleellisena erona on, että tiedostot pitää ensin avata ennen käsittelyä ja sitten sulkea käsittelyn jälkeen. Näyttöä tai näppäimistöä ei avata eikä suljeta, vaan voidaan ajatella, että ne ovat jatkuvasti auki.

Jotta ohjelmassa voitaisiin käsitellä tiedostoja, tarvitaan alkuun direktiivi

#include <fstream.h>

Jokaiselle tiedostolle täytyy luoda tunnus (olio), jonka avulla siihen viitataan, aivan kuten cin:llä viitattiin näppäimistöön ja cout:lla näyttöön. Tämä tapahtuu joko sanalla ifstream, jos halutaan avata tiedosto lukemista varten, tai sanalla ofstream, jos halutaan avata tiedosto kirjoittamista varten. Mutta tämä ei vielä riitä, vaan on myös kerrottava, mihin konkreettiseen (tietokoneen levyllä sijaitsevaan) tiedostoon tuo tunnus liittyy. Tämä taas tehdään jäsenfunktiolla open.

Esimerkkejä tiedostojen avaamisesta:

ifstream syotto;            // avataan syöttötiedosto 
syotto.open("tiedot.txt");  //  lukemista varten
...
ofstream tulostus;          // avataan tulostustiedosto 
tulostus.open("tulos.txt"); //  kirjoittamista varten
...

Tässä syotto ja tulostus ovat ohjelman sisäisiä tunnuksia eli nimiä käsiteltäville tiedostoille, aivan kuten muuttujienkin nimet. Sen sijaan tiedot.txt jatulos.txt ovat tiedostojen "oikeat" nimet siinä muodossa kuin käyttöjärjestelmä ne tunnistaa.

Koska pelkällä tiedoston tunnuksella ei tee mitään ennen kuin se on liitetty johonkin levytiedostoon, on olemassa myös lyhyempi (ja yleisemmin käytetty) tapa avata tiedosto:

ifstream syotto("tiedot.txt");  // syöttötiedosto
...
ofstream tulostus("tulos.txt"); // tulostustiedosto
...

Tässä luodaan tiedostolle tunnus ja samanaikaisesti liitetään se johonkin levytiedostoon. Tämä tapa on vaihtoehtoinen edellä esitetyn tavan kanssa; ei siis käytetä molempia samalle tiedostolle!

Tiedoston, joka avataan lukemista varten, täytyy olla olemassa. Jos tiedostoa ei levyltä löydy, avaaminen epäonnistuu, eikä lukemista voi suorittaa. Tiedoston avaaminen voi epäonnistua myös muusta syystä, joten onnistuminen pitää aina tarkistaa, ennen kuin tiedostoa ryhdytään käsittelemään.

Jos tiedoston avaaminen onnistui, on tiedoston tunnuksella jokin nollasta eroava kokonaislukuarvo (siis tosi). Jos taas avaus epäonnistui, on tunnuksella arvo nolla (eli epätosi). Siten onnistuminen on helppo tarkistaa; esimerkiksi, joko seuraavasti:

ifstream tiedosto("tdsto.txt");
if (tiedosto) {
 .
 .  // avaaminen onnistui,
 .  //  voidaan käsitellä tiedostoa normaalisti
}

tai seuraavasti:

ifstream tiedosto("tdsto.txt");
if (!tiedosto) { // huomaa negaatio
 .
 .  // avaaminen epäonnistui,
 .  //  käsitellään virhetilanne jollain tavoin
}

Myös tulostustiedoston avaamisen onnistuminen täytyy tarkistaa samalla tavoin.

Tiedoston, joka avataan kirjoittamista varten, ei tarvitse olla olemassa; tarvittaessa luodaan uusi tiedosto. Mutta on huomattava, että jos avataan kirjoittamista varten jo olemassa oleva tiedosto, tuhoutuu tiedostossa aikaisemmin ollut tieto. Jos halutaan avata tulostustiedosto vanhoja tietoja tuhoamatta (append), tehdään se seuraavasti:

ofstream tulos("tdsto.txt", ios::app);

Tällöin kirjoittaminen tapahtuu tiedoston loppuun, vanhojen tietojen perään.