Grafikus C# – Windows Forms tanfolyam › 10.2 lecke Windows Forms · 10.2 lecke · adatfolyamok A StreamReader, StreamWriter és using
File.ReadAllText és társai egy lépésben olvasnak vagy írnak: kényelmesek, de a teljes fájlt a memóriába töltik, és nem adnak közbülső irányítást. Egy 2 GB-os naplófájl beolvasása így összeomlást okozhat, és a hosszú írás közben a program nem tud „élő” lenni. A megoldás az adatfolyam (stream): a fájlt részletenként olvasod vagy írod. Ebben a leckében a StreamReader és a StreamWriter használatát, a FileStream módjait (FileMode, FileAccess, FileShare), a using szerepét, a pufferelést és a Flush jelentőségét tanulod meg.
A lecke végére
- érted az adatfolyam fogalmát, és tudod, mikor jobb a
StreamReaderaReadAllText-nél; - soronként olvasol (
ReadLineciklus,File.ReadLines), és kezeled a fájl végét; - írsz és fűzöl hozzá (
StreamWriter,append), és érted aFlushés azAutoFlushszerepét; - a
FileStreamFileMode,FileAccess,FileShareértékeit választod; - mindig
usingblokkban dolgozol, és tudod, mi történik nélküle (zárolt fájl, elveszett adat); - nagy fájlt mutatsz be előrehaladással (
Position/Length).
Mielőtt elkezded
Ehhez a leckéhez a 10.1 lecke (File, Path), a 9.8 lecke (Dispose, using) és a 4.7 lecke (kivételkezelés) szükséges.
StreamReader: olvasás soronként
// klasszikus: ReadLine ciklus, a fájl végén null
int sorszam = 0;
using (StreamReader olvaso = new StreamReader(ut))
{
string sor;
while ((sor = olvaso.ReadLine()) != null)
{
sorszam++;
if (sor.Contains("HIBA")) { lstHibak.Items.Add(sorszam + ": " + sor); }
}
}
// egyszerűbb: File.ReadLines lusta felsorolás (egyszerre egy sor van a memóriában)
foreach (string sor2 in File.ReadLines(ut))
{
if (sor2.StartsWith("#")) { continue; } // megjegyzés kihagyása
}
// teljes tartalom (kicsi fájlnál)
using (StreamReader olvaso2 = new StreamReader(ut))
{
string mind = olvaso2.ReadToEnd();
}
// karakter szinten (feldolgozóknál, 10.5 lecke): Read() a következő karakter kódja, -1 a fájl vége
using (StreamReader olvaso3 = new StreamReader(ut))
{
int c;
while ((c = olvaso3.Read()) != -1)
{
char betu = (char)c;
}
}StreamReader a bájtokat szöveggé alakítja (kódolás, 10.3 lecke), és a ReadLine sorokat ad.ReadLine a fájl végén null értéket ad. Üres sor ("") nem a vége: az egy üres sor a fájlban. A while ((sor = ...) != null) a szokásos minta.ReadAllLines a teljes listát tömbbe tölti (memória), a ReadLines lusta: soronként ad, és megszakítható (break). Nagy fájlnál a ReadLines vagy a StreamReader.ReadAllText a fájl méretének többszörösét foglalhatja (a szöveg UTF-16 kódolású a memóriában). 100 MB-os fájlnál ez több száz MB; GB-os fájlnál összeomlás.Jósolj!
A fájlban 3 sor van, a második üres (alma, (üres), körte). A while ((sor = olvaso.ReadLine()) != null) ciklus hányszor fut le, és mi a sor értéke másodszorra?
Jóslat ellenőrzése
Háromszor; a másodiknál a sor értéke "" (üres szöveg, nem null). A ciklus csak a fájl végén áll meg, ahol a ReadLine null-t ad.
StreamWriter: írás és hozzáfűzés
// új fájl (vagy felülírás): append = false
using (StreamWriter iro = new StreamWriter(ut, false))
{
iro.WriteLine("Név;Pontszám");
foreach (Diak d in diakok)
{
iro.WriteLine(d.Nev + ";" + d.Pont);
}
} // itt záródik: a puffer kiíródik, a fájl felszabadul
// hozzáfűzés a meglévő végére: append = true
using (StreamWriter naplo = new StreamWriter(naploUt, true))
{
naplo.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " | " + uzenet);
}
// hosszú életű író (naplózó): egyszer megnyitva; az AutoFlush minden írás után a lemezre küld
private StreamWriter folyamatosNaplo;
private void NaploIndit()
{
folyamatosNaplo = new StreamWriter(naploUt, true) { AutoFlush = true };
}
private void Naploz(string uzenet)
{
folyamatosNaplo.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " | " + uzenet);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (folyamatosNaplo != null) { folyamatosNaplo.Dispose(); } // a hosszú életű erőforrás felszabadítása (9.8 lecke)
}StreamWriter az adatot előbb pufferbe gyűjti, és egyszerre írja ki (gyorsabb). A Flush() azonnal kiírja a puffert. A Dispose (using vége) is meghívja. Ha a program összeomlik using és Flush nélkül, a pufferben lévő adat elveszik.AutoFlush = true minden Write után kiírja a puffert: naplóknál hasznos (összeomlás után is megvan), de lassabb. Tömeges írásnál (több ezer sor) kapcsold ki.new StreamWriter(ut, false) felülír, a true hozzáfűz. Ez a WriteAllText és AppendAllText megfelelője (10.1 lecke).File.AppendAllText egyszerű (minden hívás megnyit és bezár). Sűrű naplózásnál (másodpercenként többször) a hosszú életű, nyitott StreamWriter hatékonyabb; ezt a FormClosed-ben zárd le.Jósolj!
A kód StreamWriter iro = new StreamWriter(ut); iro.WriteLine("Fontos adat"); módon ír, using és Dispose nélkül, majd a program befejeződik. Mi van a fájlban?
Jóslat ellenőrzése
Gyakran üres fájl (vagy csak részleges tartalom): az adat a pufferben maradt, és sosem került a lemezre, mert nem volt Flush vagy Dispose. A fájl ráadásul zárolt maradhat, amíg a folyamat él. Mindig using.
FileStream: mód, hozzáférés és megosztás
A StreamReader/StreamWriter mögött egy FileStream áll: ez a fájl bájtjait olvassa/írja, és itt döntheted el, hogyan nyisd meg a fájlt. Három fogalom kell:
| Beállítás | Értékek | Jelentés |
|---|---|---|
FileMode | Open, OpenOrCreate, Create, CreateNew, Append, Truncate | Mi legyen, ha a fájl létezik / nem létezik? A Create felülír, a CreateNew hibát ad, ha már van, az Append a végére ír. |
FileAccess | Read, Write, ReadWrite | Mire használod a folyamot. |
FileShare | None, Read, Write, ReadWrite | Mit engedsz másnak, amíg te használod (például olvashat-e közben más program). |
// egy másik program által írt (nyitva tartott) naplófájl olvasása: engedd a másiknak az írást
using (FileStream fs = new FileStream(naploUt, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader olvaso = new StreamReader(fs))
{
txtNaplo.Text = olvaso.ReadToEnd();
}
// új fájl, amely nem írhat felül meglévőt
try
{
using (FileStream fs = new FileStream(ut, FileMode.CreateNew, FileAccess.Write, FileShare.None))
using (StreamWriter iro = new StreamWriter(fs))
{
iro.WriteLine("Új tartalom");
}
}
catch (IOException)
{
MessageBox.Show("Ez a fájl már létezik."); // a CreateNew nem ír felül
}File.ReadAllText alapértelmezett megosztása FileShare.Read: ha egy másik program írásra nyitva tartja a fájlt, az olvasás IOException kivétellel hibázik. A FileShare.ReadWrite engedi a közös használatot.Create létrehozza vagy felülírja; a Truncate csak meglévő fájlt nyit meg, és kiüríti (hiba, ha nincs). A CreateNew biztonságos, ha nem akarsz véletlenül felülírni.new StreamReader(fs) a megnyitott folyamra épül. Mindkettő IDisposable: két egymásba fűzött using; a külső Dispose a belsőt is lezárja, de a kettős using a biztos.fs.Length a fájl mérete, a fs.Position a pillanatnyi hely bájtban: ebből számolható az előrehaladás (lásd lent).Jósolj!
Egy másik program (például egy naplózó szolgáltatás) írásra nyitva tartja a naplo.txt fájlt. A te programod a File.ReadAllText("naplo.txt") hívást hajtja végre. Mi történik?
Jóslat ellenőrzése
Gyakran IOException (a fájlt másik folyamat használja): a ReadAllText nem engedi a közös írást. A FileStream FileShare.ReadWrite beállításával olvashatod a közben írt naplót.
Nagy fájlok: soronként és előrehaladással
// a keresés nagy fájlban: soronként, előrehaladással; az eredmények száma korlátozott
private int Keres(string ut, string szo, int maxTalalat)
{
int talalat = 0;
long sorszam = 0;
using (FileStream fs = new FileStream(ut, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader olvaso = new StreamReader(fs))
{
string sor;
while ((sor = olvaso.ReadLine()) != null)
{
sorszam++;
if (sor.IndexOf(szo, StringComparison.CurrentCultureIgnoreCase) >= 0)
{
lstTalalat.Items.Add(sorszam + ": " + sor);
talalat++;
if (talalat >= maxTalalat) { break; } // a korlát megvéd a memória- és időtúllépéstől
}
if (sorszam % 5000 == 0)
{
pbHaladas.Value = (int)(fs.Position * 100 / Math.Max(1, fs.Length)); // az olvasott bájtok aránya
Application.DoEvents(); // vészmegoldás: a felület frissül (helyesen: háttérszál, 11. fejezet)
}
}
}
return talalat;
}ListBox ezt nem bírja: legyen felső korlát (például 1000), és jelezd, ha elérted.fs.Position a már olvasott bájtok száma, a Length a teljes méret: a kettő hányadosa a készültség. A StreamReader pufferel, ezért a pozíció kissé előrébb jár, mint az utolsó feldolgozott sor: ez elfogadható.Application.DoEvents() csak vészmegoldás (újrabelépési hibákat okozhat). A helyes megoldás a háttérszál és az async/await (11. fejezet).try–catch blokkal; a ReadToEnd és a ReadAllLines nagy fájlnál tilos.Jósolj!
A ReadAllLines hívás egy 3 GB-os naplóra fut le egy 8 GB RAM-os gépen. Mi történik?
Jóslat ellenőrzése
A program OutOfMemoryException kivétellel leállhat (vagy a gép erősen lelassul): a szöveg a memóriában UTF-16 kódolású (a fájl kb. kétszerese), és a sorok külön objektumok. A File.ReadLines vagy a StreamReader egyszerre csak egy sort tart a memóriában.
Mit tegyél ide: a naplózó és fájlnézegető: a találati lista, az előrehaladás-jelző és az állapotsor.Javasolt fájlnév: winforms-10-2-naplo.webp · Alt szöveg: A naplózó és nagyfájl-nézegető program
Hibakeresés: te vagy a hibadetektív
Mi a baj, és hogyan javítod?
Gondold végig az okot, és csak utána nyisd le a megoldást.
1. A fájl üres marad
StreamWriter iro = new StreamWriter(ut);
iro.WriteLine("adat"); // nincs Flush, nincs DisposeHiba és javítás
Az adat a pufferben maradt. Használj using blokkot, vagy hívj Flush és Dispose metódust.
2. A fájl nem törölhető a program használata után
Egy beolvasás után a A File.Delete IOException kivételt ad.Ok és javítás
StreamReader nincs lezárva (using hiányzik), ezért a fájl zárolt. Használj using blokkot.
3. A hozzáfűzés felülírja a naplót
using (StreamWriter iro = new StreamWriter(naploUt)) // append nélkül
{
iro.WriteLine(uzenet);
}Hiba és javítás
A második paraméter (append) alapértéke false: felülír. Hozzáfűzéshez new StreamWriter(naploUt, true).
4. Az első sor kimarad vagy duplán jön
string fejlec = olvaso.ReadLine();
while (olvaso.ReadLine() != null)
{
string sor = olvaso.ReadLine(); // a feltételben már elolvasta a sort!
}Hiba és javítás
Kétszeri ReadLine hívás: a ciklusfeltétel elfogyasztja a sort. Használd a while ((sor = olvaso.ReadLine()) != null) mintát.
5. NullReferenceException az utolsó sornál
while (!olvaso.EndOfStream)
{
string sor = olvaso.ReadLine();
string[] m = sor.Split(';'); // a sor lehet null, ha valami közben megváltozott
}Hiba és javítás
Az EndOfStream ellenőrzés és a ReadLine között a helyzet megváltozhat (főleg hálózati vagy írás alatt álló fájlnál). A while ((sor = ReadLine()) != null) minta biztonságosabb, mert a null ellenőrzés az olvasás részeként történik.
6. A program lefagy a hosszú beolvasás alatt
Nagy fájlnál az ablak nem reagál. A ciklus a felület szálán fut. Átmeneti megoldás: Ok és javítás
DoEvents és korlát; a helyes: háttérszál és async (11. fejezet).
Mini projekt: naplózó és nagyfájl-nézegető
Készíts programot két résszel, amely az adatfolyamok használatát mutatja:
- Naplózó fül:
txtUzenet+ Naplóz gomb; a naplófájl az adatmappában (10.1 leckeAdatMappa())naplo.txt; Egyszerű mód (File.AppendAllText) és Folyamatos mód (hosszú életűStreamWriter,AutoFlush) választható;btnTeszt: 10 000 sor beírása mindkét móddal, aStopwatchidőket kiírja. - Naplónézegető: Megnyitás... (a
FileShare.ReadWritemiatt akkor is megnyílik, ha a naplózó írja); a fájl utolsó 200 sora (a végéről olvasás: aFileStream.Seekvagy egyszerű: a teljes fájl végigolvasása egy 200 elemű körkörös sorral). - Kereső:
txtSzo+ Keresés; a találatok (sorszám: sor) a listában, legfeljebb 1000;ProgressBaraz előrehaladásról; Mégse jelző (a ciklus megszakadhat); az eredmény darabszáma és az eltelt idő az állapotsorban. - Információ: a fájl mérete, a sorok száma (egy gyors számláló ciklus, a méretkorlát figyelmeztetéssel: ha > 200 MB, megerősítés kell), az első és utolsó sor.
- Hibatűrés: nem létező, zárolt, hozzáférés nélküli fájl, üres fájl, nagyon hosszú sor, bináris fájl; mindegyikre érthető üzenet; a program nem omlik össze.
- Erőforrások: minden olvasó és író
usingblokkban; a folyamatos író aFormClosed-ben lezárva. - Teszteld: 10 000 soros napló mindkét móddal, a nézegető megnyitása írás közben, 100 MB-os fájlban a keresés (a felület fagyását jegyezd fel: a 11. fejezetben javítjuk), üres és nem létező fájl.
Megoldás megnyitása (próbáld ki előbb önállóan!)
Az utolsó 200 sor megtalálása egyszerű, memóriabarát módszerrel: Queue<string> korlátozott mérettel, a fájl végigolvasása közben.
private StreamWriter folyamatos;
private string naploUt;
private bool megszakit = false;
private void Form1_Load(object sender, EventArgs e)
{
string mappa = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MiniNaplo");
Directory.CreateDirectory(mappa);
naploUt = Path.Combine(mappa, "naplo.txt");
}
private void Naploz(string uzenet)
{
string sor = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " | " + uzenet;
try
{
if (rbFolyamatos.Checked)
{
if (folyamatos == null) { folyamatos = new StreamWriter(new FileStream(naploUt, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) { AutoFlush = true }; }
folyamatos.WriteLine(sor);
}
else
{
File.AppendAllText(naploUt, sor + Environment.NewLine);
}
}
catch (IOException ex) { tsslUzenet.Text = "A naplózás nem sikerült: " + ex.Message; }
catch (UnauthorizedAccessException) { tsslUzenet.Text = "Nincs jogosultság a naplófájlhoz."; }
}
private void btnTeszt_Click(object sender, EventArgs e)
{
foreach (bool folyamat in new bool[] { false, true })
{
rbFolyamatos.Checked = folyamat;
Stopwatch ora = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++) { Naploz("Teszt sor " + i); }
ora.Stop();
lstEredmeny.Items.Add((folyamat ? "Folyamatos" : "Egyszerű") + ": " + ora.ElapsedMilliseconds + " ms");
}
}
private void btnMegnyit_Click(object sender, EventArgs e)
{
Queue<string> utolso = new Queue<string>();
long db = 0;
try
{
using (FileStream fs = new FileStream(naploUt, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader olvaso = new StreamReader(fs))
{
string sor;
while ((sor = olvaso.ReadLine()) != null)
{
db++;
utolso.Enqueue(sor);
if (utolso.Count > 200) { utolso.Dequeue(); } // csak az utolsó 200 sor marad a memóriában
}
}
txtNezet.Lines = utolso.ToArray();
tsslUzenet.Text = db + " sor, a végén 200 látszik.";
}
catch (FileNotFoundException) { tsslUzenet.Text = "Még nincs naplófájl."; }
catch (IOException ex) { tsslUzenet.Text = "A fájl nem olvasható: " + ex.Message; }
}
private void btnKeres_Click(object sender, EventArgs e)
{
string szo = txtSzo.Text.Trim();
if (szo.Length == 0 || !File.Exists(naploUt)) { return; }
lstTalalat.Items.Clear();
megszakit = false;
Stopwatch ora = Stopwatch.StartNew();
int talalat = 0;
long sorszam = 0;
try
{
using (FileStream fs = new FileStream(naploUt, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader olvaso = new StreamReader(fs))
{
string sor;
while ((sor = olvaso.ReadLine()) != null && !megszakit)
{
sorszam++;
if (sor.IndexOf(szo, StringComparison.CurrentCultureIgnoreCase) >= 0)
{
lstTalalat.Items.Add(sorszam + ": " + sor);
if (++talalat >= 1000) { tsslUzenet.Text = "Az első 1000 találat látszik."; break; }
}
if (sorszam % 5000 == 0)
{
pbHaladas.Value = (int)(fs.Position * 100 / Math.Max(1, fs.Length));
Application.DoEvents(); // vészmegoldás, 11. fejezet: háttérszál
}
}
}
}
catch (IOException ex) { tsslUzenet.Text = "A keresés nem sikerült: " + ex.Message; }
pbHaladas.Value = 100;
tsslUzenet.Text = talalat + " találat, " + sorszam + " sor, " + ora.ElapsedMilliseconds + " ms";
}
private void btnMegse_Click(object sender, EventArgs e) { megszakit = true; }
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (folyamatos != null) { folyamatos.Dispose(); }
}Mit tegyél ide: a kész program: a két mód mérési eredménye, a naplónézegető és egy keresés találatai.Javasolt fájlnév: winforms-10-2-kesz.webp · Alt szöveg: A kész naplózó és nézegető
Három önálló gyakorlófeladat
Egyszerre csak egyet csinálj: tervezd meg, írd meg, futtasd, ellenőrizd, és csak utána nyisd ki a megoldást.
1. Sorok számlálása szavanként
Számold meg egy fájlban a szavak előfordulását (kis- és nagybetűtől függetlenül), és írd ki a 10 leggyakoribbat. Melyik adatszerkezet?Egy lehetséges megoldás
Dictionary<string, int>: soronként bontod a szavakat (Split), és növeled a számlálót; a végén rendezel.Dictionary<string, int> szamlalo = new Dictionary<string, int>();char[] elvalaszto = { ' ', ',', '.', ';', ':', '!', '?', '(', ')', '\t' };foreach (string sor in File.ReadLines(ut)){ foreach (string szo in sor.ToLowerInvariant().Split(elvalaszto, StringSplitOptions.RemoveEmptyEntries)) { int db; szamlalo.TryGetValue(szo, out db); szamlalo[szo] = db + 1; }}var top = szamlalo.OrderByDescending(p => p.Value).Take(10);
2. Fájl másolása adatfolyammal
Másolj egy nagy fájlt 80 KB-os darabokban, és mutass előrehaladást. Mit használsz? Két Egy lehetséges megoldás
FileStream és egy bájttömb puffer: olvasás a forrásból, írás a célba, amíg a Read 0-t ad. A Stream.CopyTo egyszerű esetben elég, de nem ad előrehaladást.byte[] puffer = new byte[81920];using (FileStream be = new FileStream(forras, FileMode.Open, FileAccess.Read))using (FileStream ki = new FileStream(cel, FileMode.CreateNew, FileAccess.Write)){ int olvasott; while ((olvasott = be.Read(puffer, 0, puffer.Length)) > 0) { ki.Write(puffer, 0, olvasott); pb.Value = (int)(be.Position * 100 / be.Length); }}
3. Szűrés új fájlba
Egy naplóból csak a HIBA szót tartalmazó sorokat írd új fájlba. Hogyan kezeled egyszerre az olvasót és az írót? Két egymásba fűzött Egy lehetséges megoldás
using: az egyik olvasó, a másik író; a ciklusban a feltételes WriteLine. Az egész fájl sosem kerül a memóriába.
Gyakorlótár: 6 további feladat
Három szinten gyakorolhatsz: alap, közepes és kihívás. Csak a próbálkozás után nyisd le a megoldást.
Alap szint
1. Mit ad a ReadLine?
Mit ad a A fájl végén ReadLine a fájl végén, és mit egy üres sornál?Megoldás megnyitása
null, üres sornál "" (üres szöveg).
2. Hozzáfűzés vagy felülírás?
Melyik kód fűz hozzá: (a) (b): a második paraméter az new StreamWriter(ut); (b) new StreamWriter(ut, true)?Megoldás megnyitása
append. Az (a) felülír.
Közepes szint
3. Melyik FileMode?
Melyiket használod: (a) csak akkor hozzon létre fájlt, ha nincs; (b) meglévő fájl kiürítése; (c) végére írás? (a) Megoldás megnyitása
CreateNew; (b) Truncate (vagy Create); (c) Append.
4. Az első sor kihagyása
Egy CSV első sora fejléc. Hogyan hagyod ki a A LINQ ReadLines felsorolásban?Megoldás megnyitása
Skip(1): File.ReadLines(ut).Skip(1); ez lusta marad.
Kihívás szint
5. Farok (tail -f)
A program folyamatosan mutassa a naplófájl végére kerülő új sorokat. Mi a megoldás elve? A Megoldás megnyitása
FileStream (FileShare.ReadWrite) pozícióját megjegyzed; egy időzítő (Timer) másodpercenként a megjegyzett pozícióról olvas, amíg van új tartalom (vagy FileSystemWatcher jelzésére). Ha a fájl rövidebb lett (rotáció), a pozíciót nullázod.
6. Naplóforgatás
A napló 1 MB felett új fájlba kerül (naplo.1.txt). Hogyan oldod meg biztonságosan? Írás előtt a Megoldás megnyitása
FileInfo.Length ellenőrzése; ha elérte a korlátot, a folyamatos író lezárása, a régi fájl átnevezése (File.Move, a legrégebbi törlése), és új író nyitása. Az átnevezés hibája (zárolt fájl) nem állíthatja le a programot (10.9 lecke).
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. Nagy fájlnál, soronkénti feldolgozásnál, ha a memóriát és az idő-irányítást védeni kell. Az adatot gyűjti, és egyszerre írja ki (gyorsabb); a A puffer nem ürül (adatvesztés), és a fájl zárolt marad. Mit engedsz másnak, amíg a fájlt használod (olvasás, írás). Lusta: egyszerre egy sort tart a memóriában, és megszakítható.1. Mikor jobb a StreamReader a ReadAllText-nél?
2. Mi a puffer szerepe a StreamWriter-ben?
Flush és a Dispose üríti.3. Mi történik using nélkül?
4. Mit jelent a FileShare?
5. Hogyan számolsz előrehaladást?
fs.Position · 100 / fs.Length.6. Mi a File.ReadLines előnye a ReadAllLines-szel szemben?
7. Mi a helyes minta a ReadLine ciklushoz?
while ((sor = olvaso.ReadLine()) != null).
Mit tudsz már?
- Adatfolyammal olvasol és írsz (
StreamReader,StreamWriter), soronként és hozzáfűzéssel. - Érted a pufferelést, a
Flushés azAutoFlushszerepét. - A
FileStreammódjait (FileMode,FileShare) feladathoz választod. - Nagy fájlt kezelsz memóriabarát módon, előrehaladással.
- Mindig
usingblokkban dolgozol.
Következő lecke: Szövegfájlok és UTF-8 kódolás
A bájtok és a karakterek viszonya: UTF-8, BOM, Windows-1250, az ékezetes betűk hibái és az átalakítás.



