Személyes eszközök
Keresés

 

A InfoWiki wikiből


Text file

A program futása során sok adatot képes előállítani, illetve sok adatot kell bekérni, amelyekkel számolni tud. Nagyon gyakori az az eset, amikor az előállított adatokat kiírjuk diszkre valamilyen file-ba. Ennek oka, hogy ott tartósan (a gép kikapcsolása esetén) is megmaradnak ezek a részeredmények, illetve ez az egyik legegyszerűbb módja annak, hogy másik program felé az adatokat publikáljuk (egyik program kiírja, másik program beolvassa).

A legegyszerűbb felépítésű file az ún. text file szerkezet. Az ilyen file-ok sorokra tagoltak, és tartalmukat akár a legegyszerűbb windows-os Jegyzettömb (notepad) alkalmazással is megtekinthető, szerkeszthető.

A text file-ok sorokat (string) tartalmaznak. Minden sor végét speciális sorvége jel zárja, amely windows-ban a \r\n karakterek (13,10 kódú karakterek), Linux alatt a \n (10 kódú karakter) van használatban. Ez persze nem annyira lényeges információ, csak ha olyan alkalmazást akarunk írni, amely mindkét platformon futásképes kell legyen.

A text file kezeléshez szükséges dolgok a System.IO névtérben vannak, ezért a using System.IO; sort bele kell írni a programunk elejére!


Text file írása

Az íráshoz a StreamWriter-t kell használni, megadván a létrehozandó file nevét:

string fname=@"c:\adatok.txt";
StreamWriter w = new StreamWriter(fname, false, Encoding.Default);
  • az első paraméter (fname) adja meg a file nevét, amelybe írni szeretnénk.
  • a második paraméter (false) azt adja meg, hogy amennyiben ilyen nevű file lenne már, akkor azt a rendszer törölje le, és üres állapotból induljon a fileba írás. Ha ide true-t adunk meg, akkor a már létező file tartalma megmarad, és amit most írunk bele majd a file-ba, az annak a végére fog íródni (hozzáfűzés, append).
  • a harmadik paraméter a file-ba írás kódlapját adja meg. Az Encoding.Default a windows-unkban használt kódlap (alapértelmezett kódlap)

A fentiek után a file-ba írás máris indulhat. Az íráshoz a már ismerős WriteLine-t kell használni, csak nem a konzolra írunk (Console.WriteLine), hanem a file-ba szeretnénk írni, melyet most a w változónk azonosít. E miatt w.WriteLine-t kell megadnunk:

double r=23.4;
w.WriteLine("Programozó=Hernyák Zoltán");
w.WriteLine("PI={0}",Math.PI);
w.WriteLine("sugár={0}",r);
w.WriteLine("Kerület={0}",2*r*Math.PI);
...

Ha minden adatot beleírtunk a file-ba, akkor a végén le kell azt zárnunk a Close() hívásával:

w.Close();
Amennyiben elfelejtjük lezárni a file-t, úgy a kiírt adatok nem kerülnek bele! Ezért ezt a lépést semiképp ne felejtsük el!


A teljes kód:

using System.IO;
 
string fname=@"c:\adatok.txt";
StreamWriter w = new StreamWriter(fname, false, Encoding.Default);
double r=23.4;
w.WriteLine("Programozó=Hernyák Zoltán");
w.WriteLine("PI={0}",Math.PI);
w.WriteLine("sugár={0}",r);
w.WriteLine("Kerület={0}",2*r*Math.PI);
w.Close();

Eredménye megtekinthető a jegyzettömb segítségével:

Image:xx_adatok_txt.png
A file tartalma a Jegyzettömb-ben


File-ból olvasás

A fileból olvasáshoz a StreamReader-t kell használni. A

string fname = @"c:\adatok.txt";
StreamReader r = new StreamReader(fname, Encoding.Default);

A megnyitás során meg kell adni

  • a file nevét (fname)
  • a file-ba íráskor használt kódlapot (ez most is a windows-unk alapértelmezett kódlapja lesz, Encoding.Default)

A file-ból olvasás során a ReadLine()-t kell használni, csak épp most nem a konzolról olvasunk (Console.ReadLine()), hanem a file-ból. A file-unkat most az r változó képviseli, ezért r.ReadLine()-al kell olvasni. A ReadLine most is string-et ad meg. Minden egyes olvasás során a file-unk egy-egy sorát kapjuk meg:

string s;
s = r.ReadLine(); // "Programozó: Hernyák Zoltán"
s = r.ReadLine(); // "PI=3,14159265358979"
s = r.ReadLine(); // "sugár=23,4"
s = r.ReadLine(); // "Kerület=147,026536188002"

Amikor befejezzük a file-ból olvasást, akkor a file-t le kell zárni a Close() segítségével:

r.Close();

A teljes kód:

using System.IO;
 
string fname = @"c:\adatok.txt";
StreamReader r = new StreamReader(fname, Encoding.Default);
string s;
s = r.ReadLine(); // "Programozó: Hernyák Zoltán"
s = r.ReadLine(); // "PI=3,14159265358979"
s = r.ReadLine(); // "sugár=23,4"
s = r.ReadLine(); // "Kerület=147,026536188002"
r.Close();


Minden sor beolvasása

Amennyiben tudjuk előre, hogy a text file-unk 4 sorból áll, akár ciklust is szervezhetünk hozzá:

using System.IO;
 
string fname = @"c:\adatok.txt";
StreamReader r = new StreamReader(fname, Encoding.Default);
for (int i=0;i<4;i++)
{
  string s = r.ReadLine(); 
  ...
}
r.Close();

Ne rontsuk el: a file bezárását nem a ciklusban, hanem a cikluson kívül csak a legvégén kell megtenni!

Sokkal gyakoribb eset, amikor nem tudjuk előre, hogy a text file-unk hány sorból áll. Ekkor a fenti for ciklus nem használható, helyette while ciklust fogalmazunk. A feltételben azt kérdezzük le, hogy elértük-e már (end of file, end of stream) a text file végét.

using System.IO;
 
string fname = @"c:\adatok.txt";
StreamReader r = new StreamReader(fname, Encoding.Default);
while (!r.EndOfStream)
{
  string s = r.ReadLine(); 
  ...
}
r.Close();

Substring

Tegyük fel, hogy a beolvasó program szeretné tudni, mennyi volt a sugár értéke. Hogyan szedjük ki ezt az információt a text file-ból?

Ehhez tudnunk kell, hogy a keresett adat a sugár= sorban található, az egyenlőség jel jobb oldalán. Minden egyes sort beolvasunk, keresvén azt a sort, amelyiknek az eleje pontosan ez a karaktersorozat:

while (!r.EndOfStream)
{
  string s = r.ReadLine(); 
  if (s.StartsWith("sugár=")) Console.WriteLine(s);
  ...
}

A StartsWith-el lehet a stringünk (sorunk) elejét megvizsgálni. A fenti if ki fogja keresni ezt a sort, és jelenleg ezt a sort kiírjuk a képernyőre.

De hogyan vegyük ki magát a számértéket a sorból? Le kell választani az s stringünkből ezt a darabkát a Substring() segítségével. Ennek meg kell adni:

  • hanyadik betűtől akarjuk leválasztani
  • hány betű hosszú darabot

Ezzel két gond is van: a hanyadik betű megadásakor ügyeljünk rá, hogy a betűk sorszámozása 0-tól kezdődik. A sugár=23,4 szövegünkben a 23,4 szakasz a 6 betűtől kezdődik, és 4 betű hosszú:

if (s.StartsWith("sugár=")) 
{
  string szam = s.Substring(6,4); // "23,4"
  double sugar = double.Parse(szam);
  Console.WriteLine("sugar beolvasas utan={0}",sugar);
}

Split

Másik (és sokkal jobb módszer) a Split használata. A Split segítségével egy sztringet több felé vághatunk szét valamilyen elválasztó karakter mentén. A sugár=23,4 sort kettévághatjuk az = jel mentén két darabra, így különválik a bal oldali rész sugár és a jobb oldali rész 23,4. A kettévágás egy string[] tömböt eredményez. A tömbünk két elemű lesz, a 0 sorszámú elem az első darab, a 1 sorszámú elem pedig a második darabka lesz:

if (s.StartsWith("sugár=")) 
{
  string[] darabok = s.Split('='); // "23,4"
  double sugar = double.Parse(darabok[1]);
  Console.WriteLine("sugar beolvasas utan={0}",sugar);
}

Miért jobb a Split mint a Substring? Ugyanis ha az értékünk nem 23,4, hanem mondjuk 123,345', amely már nem 4 karakter hosszú, akkor a fenti Substring máris nem jól működik. Van persze arra mód, hogy ezen segítsünk a string hosszából (s.Length) kiindulva, de a Split annyival egyszerűbben működik, hogy kár ezzel foglalkozni.



Hernyák Zoltán
A lap eredeti címe: „http://wiki.ektf.hu/wiki/Mp1/page850
Nézetek
nincs sb_3.215.180.226 cikk