C# fájlok kezelése

11. osztály 11.évf_c# C# programozás Programozás

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ó!

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);
                }
            }
        }
    }
}