Adatok beolvasása fájlból
A fájlok olvasásához a System,IO osztályt fogjuk használni, tehát ezt a program elején importálni kell! Using System.IO. A C# adatfolyamot használ a ki és bemeneti műveletekhez. (FileStream) A FileStream úgy működik, hogy meg kell adni neki első paraméternek a fájl nevét, elérési útját. Ha egy mappában van a programmal, akkor elég a nevét. Ha nem, akkor többféle megoldás is van:
FileStream fs = new FileStream(@”C:\mappa\mappa2\adatok.txt”, FileMode.Open);
Vagy:
FileStream fs = new FileStream(„C:\\mappa\\mappa2\\adatok.txt”, FileMode.Open);
A FileMode segítségével adjuk meg, mit akarunk az adott fájllal.
- Create Létrehoz egy új fájlt, ha már létezik, a tartalmát kitörli.
- CreateNew Ugyanaz, mint az előző, de ha már létezik a fájl, akkor kivételt dob.
- Open Megnyit egy fájl, ha nem létezik, kivételt dob.
- OpenOrCreate Ugyanaz, mint az előző, de ha nem létezik, akkor létrehozza a fájlt.
- Append Megnyit egy fájlt, és automatikusan a végére pozicionál. Ha nem létezik, létrehozza. (hozzáfűzés tulajdonképpen)
- Truncate Megnyit egy létező fájlt, és törli a tartalmát. Ebben a módban a fájl tartalmát nem lehet olvasni (egyébként kivételt dob).
A programunk egy logikai fájlnévvel fog dolgozni, ez a StreamReader résznél látható. A StreamReader sr = new StreamReader(fajltartalma); sorral kapcsoljuk össze a fizikai és a logikai fájlt.
Másik lehetőség a File.ReadAllLines
metódus a fájl teljes tartalmát beolvassa és visszaadja string tömbként, a sorokat a tömb külön elemekként kezeli. Ezt a módszert akkor célszerű használni, ha a teljes fájlt szeretnénk beolvasni. Azonban ha a fájl túl nagy, akkor az egész fájl beolvasása memóriaproblémákat okozhat, és csökkentheti a program teljesítményét. „Párja” a File.WriteAllLines.
Példa: Hozzunk létre egy új txt fájlt teszt.txt néven! Írjunk bele pár szót, majd írjuk ki az adatokat a fájlba! Ellenőrzésként olvassuk be a fájl tartalmát!
using System;
using System.IO;
class Test
{
public static void Main()
{
string path = @"c:\temp\teszt.txt";
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("Programozás");
sw.WriteLine("Adatbázis kezelés");
sw.WriteLine("Weblap szerkesztés");
}
}
// Open the file to read from.
using (StreamReader sr = File.OpenText(path))
{
string s;
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
}
}
}
2. Példa: Készítsünk egy txt fájlt, például autómárkákkal, majd a programmal beolvassuk a tartalmát. A fájlnak a futtatható programunk mellett kell lennie, vagy teljes elérési utat kell megadnunk. Visual Studio-ban például hozzáadhatunk egy „Text File”-t a projekthez (jobb klikk a jobb oldali panelben, majd Add New Item), ezután a fájlon jobb gombbal kattintva Properties, és a Copy To Output Directory sorban válasszuk a Copy Always lehetőséget!
using System;
using System.IO;
namespace fajlkezeles
{
class Program
{
static void Main(string[] args)
{
FileStream fajltartalma = new FileStream("autok.txt", FileMode.Open);
StreamReader sr = new StreamReader(fajltartalma);
string s = sr.ReadLine();
while (s != null) //amíg nem értünk a fájl végéhez
{
Console.WriteLine(s); //kiíratjuk az aktuális sor tartalmát s = sr.ReadLine(); //beolvassuk a következő sor tartalmát }
sr.Close(); fajltartalma.Close(); Console.ReadKey();
}
}
}
Hibakezelés
A hibakezelés elég fontos mozzanat, mert amatőrségre vall, ha a program a „gyári” hibaüzeneteket dobja fel, vagy esetleg lefagy. A try és a catch utasítással lehet elkapni, és lekezelni a hibákat. A try részbe írunk például egy fájl beolvasást, a catch részbe pedig írhatunk saját hibaüzenetet, ha például a keresett fájl nem található.
A leggyakoribb hibaüzenetek fájlkezeléskor. A try után több catch is használható!
- System.IO.IOException, az alap osztálya az összes System.IO hibának.
- System.IO.FileNotFoundException. fájl nem található
- System.IO.DirectoryNotFoundException. könyvtár nem található
- DriveNotFoundException. meghajtó nem található
- System.IO.PathTooLongException. túl hosszú elérési út
- System.UnauthorizedAccessException. hozzáférés hiba, például írásvédett a fájl, vagy az adott felhasználónak nincs megfelelő hogosultsága
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
var sw = OpenStream(@".\fajl.txt");
if (sw is null)
return;
sw.WriteLine("Első mondat.");
sw.WriteLine("Második sor szövege...");
sw.Close();
}
static StreamWriter OpenStream(string path)
{
if (path is null) {
Console.WriteLine("Hiányzik az elérési út!");
return null;
}
try {
var fs = new FileStream(path, FileMode.CreateNew);
return new StreamWriter(fs);
}
catch (FileNotFoundException) {
Console.WriteLine("A fájl, vagy a megadott könyvtár nem található!");
}
catch (DirectoryNotFoundException) {
Console.WriteLine("A megadott fájl, vagy könyvtár nem található!");
}
catch (DriveNotFoundException) {
Console.WriteLine("A megadott meghajtó nem található!");
}
catch (PathTooLongException) {
Console.WriteLine("Az elérési út túl hosszú!");
}
catch (UnauthorizedAccessException) {
Console.WriteLine("Nincs jogosultsága a fájl módosításához!");
}
}
}
Adatok kiírása fájlba
3. példa: Ebben a példában előállítunk 10 darab, 0-50 közötti véletlen számot, majd kiírjuk őket a képernyőre és fájlba is!
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace hibakezeles
{
class Program
{
static void Main(string[] args)
{
string fajlnev = "szamok.txt";
Random veletlenszam = new Random();
int[] a = new int[10]; //10 elemű tömb int i = 0; StreamWriter ir = null; //a logikai fájl neve, ez egy üres fájl lesz Random veletlenszam = new Random();
Console.WriteLine("A számok:");
for (int i = 0; i < 10; i++) //tömb feltöltése véletlen számokkal, és kiíratás
{
a[i] = veletlenszam.Next(51);
Console.Write("{0,5}", a[i]);
}
try //hibakezelés miatt kell a try
{
ir = new StreamWriter(fajlnev); //itt adjuk meg a fájl nevét
for (int i = 0; i < 10; i++)
ir.Write("{0,5}", a[i]); //kiírjuk a 10db számot a fájlba
ir.Close(); //fájl lezárása }
catch (IOException)
{
Console.WriteLine("I/O hiba!"); //ha hiba lép fel ezt fogja kiírni
}
Console.ReadKey();
}
}
}
4. példa: Tanulók nevének és informatika jegyük átlagának bekérése, majd mentése fájlba. Elég 5db diák adatát bekérni, a jegyek átlaga legyen 3 tizedesjegy pontos. A neveket és a jegyeket egy tömbben tároljuk.
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace atlagmentes
{ class Program
{ static void Main(string[] args)
{ string fajlnev = "atlagok.txt"; //ebben a fájlban fogunk tárolni string nev = "";
string[] a = new string[5]; //az 5 elemű tömb létrehozása int i = 0;
double atlag = 0;
StreamWriter kiiras = null; // az üres logikai fájl létrehozása
for (i=0; i<5; i++) //tömb feltöltése a bekért adatokkal {
Console.Write("Tanuló neve:"); nev=Console.ReadLine(); Console.Write("Átlaga:");
atlag = Convert.ToDouble(Console.ReadLine());
a[i] = nev + " " + atlag;
}
try //adatok kiírása fájlba
{ kiiras = new StreamWriter(fajlnev);
for (i = 0; i < 5; i++)
kiiras.WriteLine(a[i]);
kiiras.Close(); }
catch (IOException) //ha nem sikerül, akkor hiba
{ Console.WriteLine("Hiba!"); }
Console.ReadKey();
} } }
5. Példa :
A következő feladatban írassuk ki a képernyőre az előzőben létrehozott fájl tartalmát (adatok.txt), és számoljuk ki a számok átlagát is!
Létrehozunk egy 5 elemű tömböt, ebbe fogjuk kiolvasni az adatok.txt sorait! Utána ezeken a tömbelemeken végigmegyünk egyesével, és szétszedjük őket! A szóközök számát fogjuk megszámolni, mivel a 2. szóköz után jönnek az átlagok. Ezek string típusúak, tehát ha számolni is akarunk velük, akkor vissza kell alakítani őket double-re! Utána már csak átlagot kell számolni, össze kell adni a számokat, és elosztani öttel. A tömb minden egyes eleme után a szovegesatlag és a db változót alapra (üresre) állítjuk, az összeghez pedig hozzáadjuk az adott sor átlagának értékét.
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace atlagszamitas
{
class Program
{ static void Main(string[] args)
{ StreamReader beolvasott = new StreamReader("atlagok.txt"); // a fájl string[] nev = new string[5]; // az 5 elemű tömbünk
string szovegesatlag = "";
string szoveg = "";
int i = 0, j = 0, db = 0;
double atlag = 0, osszeg = 0;
Console.WriteLine("Név, átlag");
try { for (i=0; i<5; i++) //soronként beolvassuk az adatokat
{ nev[i] = beolvasott.ReadLine(); Console.WriteLine(nev[i]); }
beolvasott.Close(); //lezárjuk a logikai fájlt
}
catch (IOException)
Console.WriteLine("I/O hiba lépett fel!"); }
for (i=0; i<5; i++)
{ szoveg = nev[i]; //A szoveg az egy sornyi adatot jelent a txt-ből
for (j=0; j<szoveg.Length; j++) //végigmegyünk az egy sornyi adaton betűnként
{ if (szoveg[j] == ' ') //keressük a szóközöket, és számoljuk őket db++;
if (db == 2) //ha megvan a 2 szóköz, akkor az adott sorból a számot megkaptuk szovegesatlag = szovegesatlag + Convert.ToString(szoveg[j]); }
atlag = Convert.ToDouble(szovegesatlag);
osszeg = osszeg + atlag;
db = 0; szovegesatlag = "";
}//eredmény formázása 0 a hely, 0.00 a 2 tizedesjegy helye
Console.WriteLine("A csoport átlaga:{0:0.00}", osszeg / 5);
Console.ReadKey();
} } }
Fájl törlése, hozzáfűzés fájlhoz, fájl tartalmának beolvasása
using System;
using System.IO;
namespace fajlkezeles2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
{
string path = "MyTest.txt";
//Létezik-e már az adott fájl? Ha nem, akkor létrehozza
if (!File.Exists(path))
{
// Fájl létrehozása
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine("Ezt a részt csak a fájl létrehozásakor írja bele egyszer.");
sw.WriteLine("----------------------------------------------------------");
}
}
// Hozzáírás a létező fájlhoz
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine("Újabb");
sw.WriteLine("sorok");
sw.WriteLine("a fájlba!");
sw.WriteLine();
}
// A fájlunk tartalmának beolvasása ellenőrzésként
using (StreamReader sr = File.OpenText(path))
{
string s = "";
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
}
Console.WriteLine("Törli a fájl? i/n");
string torles = Console.ReadLine();
if (torles == "i")
{
File.Delete(path);
}
}
}
}
}