Odczyt plików w C# – File i StreamReader

Nauczysz się wczytywać dane z plików tekstowych: cały plik naraz, linia po linii oraz obsługiwać błędy i kodowanie.

System.IO File.ReadAllText ReadAllLines StreamReader try-catch
01

Przestrzeń nazw System.IO

Wszystkie operacje na plikach w C# znajdują się w przestrzeni nazw System.IO. Musimy ją dołączyć na początku programu.

cs/UsingSystemIO.cs C#
using System.IO;

class Program
{
    static void Main()
    {
        // Teraz możemy używać klas File, StreamReader, Path...
    }
}

Najważniejsze klasy do odczytu plików

KlasaDo czego służy?
FileStatyczna klasa do prostych operacji (cały plik naraz)
StreamReaderOdczyt linia po linii (dla dużych plików)
PathOperacje na ścieżkach plików
DirectoryOperacje na folderach
Która metoda odczytu?

Mały plik (do kilku MB) → File.ReadAllText() lub ReadAllLines()
Duży plik (dziesiątki MB+) → StreamReader (czyta linia po linii, oszczędza pamięć)

02

Sprawdzanie czy plik istnieje

Przed odczytem zawsze sprawdź czy plik istnieje – unikniesz błędów!

cs/FileExists.cs C#
using System.IO;

string nazwaPliku = "dane.txt";

if (File.Exists(nazwaPliku))
{
    Console.WriteLine("Plik istnieje - mogę go odczytać!");
    string zawartosc = File.ReadAllText(nazwaPliku);
    Console.WriteLine(zawartosc);
}
else
{
    Console.WriteLine("Plik nie istnieje!");
}
File.Exists() zwraca bool

File.Exists(ścieżka) zwraca true jeśli plik istnieje, false jeśli nie istnieje. Nie rzuca wyjątku!

03

File.ReadAllText() – cały plik jako string

Najprostsza metoda – wczytuje cały plik do jednej zmiennej string.

cs/ReadAllText.cs C#
using System.IO;

// Wczytanie całego pliku do jednego stringa
string zawartosc = File.ReadAllText("plik.txt");

Console.WriteLine("Zawartość pliku:");
Console.WriteLine(zawartosc);

// Możemy użyć metod stringowych
Console.WriteLine($"Liczba znaków: {zawartosc.Length}");
Console.WriteLine($"Zawiera 'C#': {zawartosc.Contains("C#")}");
plik.txt
na dysku
ReadAllText()
string
cały tekst w pamięci
Kiedy NIE używać ReadAllText?

Dla bardzo dużych plików (setki MB) – cały plik trafia do pamięci RAM! Użyj wtedy StreamReader.

04

File.ReadAllLines() – tablica linii

Wczytuje plik i zwraca tablicę stringów – każda linia to osobny element.

cs/ReadAllLines.cs C#
using System.IO;

// Wczytanie pliku jako tablicy linii
string[] linie = File.ReadAllLines("plik.txt");

Console.WriteLine($"Plik ma {linie.Length} linii");

// Iteracja przez wszystkie linie
foreach (string linia in linie)
{
    Console.WriteLine(linia);
}

// Dostęp do konkretnej linii (indeks od 0!)
Console.WriteLine($"Pierwsza linia: {linie[0]}");
Console.WriteLine($"Ostatnia linia: {linie[linie.Length - 1]}");
plik.txt
Linia 1
Linia 2
Linia 3
ReadAllLines()
string[]
[0] „Linia 1”
[1] „Linia 2”
[2] „Linia 3”

Kiedy używać ReadAllLines?

Użyj ReadAllLines gdy…Użyj ReadAllText gdy…
Przetwarzasz plik linia po liniiPotrzebujesz całego tekstu jako jeden string
Czytasz pliki CSV, logi, listyWyszukujesz tekst w całym pliku
Chcesz dostęp do konkretnej liniiWyświetlasz całą zawartość
05

StreamReader – odczyt linia po linii

StreamReader czyta plik linia po linii – idealny dla dużych plików, bo nie ładuje całości do pamięci.

cs/StreamReader.cs C#
using System.IO;

// using automatycznie zamyka plik po zakończeniu bloku!
using (StreamReader reader = new StreamReader("plik.txt"))
{
    string linia;
    
    // ReadLine() zwraca null gdy koniec pliku
    while ((linia = reader.ReadLine()) != null)
    {
        Console.WriteLine(linia);
    }
}
// Tutaj plik jest już automatycznie zamknięty
Co robi using?

Instrukcja using automatycznie zamyka plik po zakończeniu bloku kodu (nawet jeśli wystąpi błąd!). Bez using musielibyśmy ręcznie wywołać reader.Close().

ReadToEnd() – reszta pliku jako string

cs/ReadToEnd.cs C#
using (StreamReader reader = new StreamReader("plik.txt"))
{
    // Czytamy pierwszą linię osobno
    string naglowek = reader.ReadLine();
    Console.WriteLine($"Nagłówek: {naglowek}");
    
    // Reszta pliku jako jeden string
    string reszta = reader.ReadToEnd();
    Console.WriteLine($"Pozostała treść:\n{reszta}");
}
MetodaZwracaOpis
ReadLine()string lub nullJedna linia (null = koniec pliku)
ReadToEnd()stringCała reszta pliku
EndOfStreamboolCzy osiągnięto koniec pliku?
06

Obsługa błędów (try-catch)

Operacje na plikach mogą generować wyjątki. Zawsze je obsługuj!

cs/TryCatch.cs C#
using System.IO;

try
{
    string zawartosc = File.ReadAllText("plik.txt");
    Console.WriteLine(zawartosc);
}
catch (FileNotFoundException)
{
    Console.WriteLine("❌ Plik nie został znaleziony!");
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("❌ Brak uprawnień do odczytu pliku!");
}
catch (IOException ex)
{
    Console.WriteLine($"❌ Błąd odczytu: {ex.Message}");
}

Najczęstsze wyjątki przy odczycie

WyjątekKiedy występuje?
FileNotFoundExceptionPlik nie istnieje
DirectoryNotFoundExceptionFolder nie istnieje
UnauthorizedAccessExceptionBrak uprawnień do odczytu
IOExceptionOgólny błąd I/O (plik zajęty itp.)
File.Exists() + try-catch?

Najlepiej użyć obu! File.Exists() dla typowych przypadków, try-catch dla nieoczekiwanych błędów (np. plik usunięty między sprawdzeniem a odczytem).

07

Kodowanie znaków (polskie znaki)

Jeśli plik zawiera polskie znaki (ą, ę, ć…), musisz określić kodowanie.

cs/Encoding.cs C#
using System.IO;
using System.Text;

// Odczyt z kodowaniem UTF-8 (obsługuje polskie znaki)
string tekst = File.ReadAllText("plik.txt", Encoding.UTF8);

// StreamReader z kodowaniem
using (StreamReader reader = new StreamReader("plik.txt", Encoding.UTF8))
{
    string linia = reader.ReadLine();
}
KodowanieOpisKiedy używać?
Encoding.UTF8Uniwersalne (polskie, emoji, wszystkie języki)Domyślny wybór!
Encoding.DefaultSystemowe (zależy od Windows)Stare pliki Windows
Encoding.ASCIITylko angielskie znakiPliki bez polskich znaków
Dziwne znaki zamiast polskich?

Jeśli widzisz Ĺ› zamiast ś, plik ma inne kodowanie niż UTF-8. Spróbuj Encoding.Default lub Encoding.GetEncoding(1250) (Windows-1250).

08

Ścieżki do plików

Ścieżka względna vs bezwzględna

cs/Sciezki.cs C#
using System.IO;

// Ścieżka WZGLĘDNA (od folderu z programem)
string wzgledna = "dane.txt";           // W tym samym folderze
string wzgledna2 = "dane/plik.txt";     // W podfolderze "dane"

// Ścieżka BEZWZGLĘDNA (pełna ścieżka)
string bezwzgledna = @"C:\Users\Jan\Dokumenty\dane.txt";

// Bieżący katalog programu
string obecnyFolder = Directory.GetCurrentDirectory();
Console.WriteLine($"Program uruchomiony z: {obecnyFolder}");
Co robi @”…”?

Symbol @ przed stringiem tworzy verbatim string – nie interpretuje znaków specjalnych. Bez tego musielibyśmy pisać "C:\\Users\\Jan" (podwójny backslash).

Path.Combine() – bezpieczne łączenie ścieżek

cs/PathCombine.cs C#
using System.IO;

// ❌ Źle – ręczne łączenie
string zle = "C:\\dane" + "\\" + "plik.txt";

// ✅ Dobrze – Path.Combine
string dobrze = Path.Combine("C:\\dane", "plik.txt");

// Można łączyć wiele części
string sciezka = Path.Combine("dane", "pliki", "dokument.txt");
// Wynik: "dane\pliki\dokument.txt" (Windows) lub "dane/pliki/dokument.txt" (Linux)
Dlaczego Path.Combine?

Automatycznie dodaje \ lub / w zależności od systemu operacyjnego. Działa poprawnie nawet gdy jedna część kończy się ukośnikiem, a druga zaczyna.

09

Częste błędy

❌ Błąd 1: Brak sprawdzenia czy plik istnieje

❌ Źle

string t = File.ReadAllText("plik.txt");
Rzuci wyjątek jeśli plik nie istnieje!

✅ Dobrze

if (File.Exists("plik.txt"))
Najpierw sprawdź!

❌ Błąd 2: Nieprawidłowe backslashe w ścieżce

❌ Źle

"C:\dane\plik.txt"
\d i \p to znaki specjalne!

✅ Dobrze

@"C:\dane\plik.txt"
lub "C:\\dane\\plik.txt"

❌ Błąd 3: Zapomnienie o using dla StreamReader

❌ Źle

StreamReader r = new StreamReader(...);
// ... użycie ...
Plik pozostaje otwarty!

✅ Dobrze

using (StreamReader r = ...)
{ ... }
Plik automatycznie zamknięty!

10

Podsumowanie

Metody odczytu plików

MetodaZwracaKiedy używać?
File.ReadAllText()stringMały plik, potrzebujesz całego tekstu
File.ReadAllLines()string[]Przetwarzanie linia po linii
StreamReader.ReadLine()stringDuże pliki, oszczędność pamięci

Metody pomocnicze

MetodaOpis
File.Exists(ścieżka)Sprawdza czy plik istnieje
Path.Combine(a, b)Łączy części ścieżki
Directory.GetCurrentDirectory()Bieżący folder programu
Złota zasada

1. Sprawdź czy plik istnieje (File.Exists)
2. Użyj try-catch dla obsługi błędów
3. Określ kodowanie dla polskich znaków (Encoding.UTF8)
4. Używaj using dla StreamReader

Zadania

Zadania praktyczne

📝 Zadanie 1: Podstawowy odczyt

Napisz program, który:

  • Sprawdza czy plik „dane.txt” istnieje
  • Jeśli tak – wyświetla jego zawartość
  • Jeśli nie – wyświetla komunikat „Plik nie istnieje”

📝 Zadanie 2: Licznik linii

Napisz program, który:

  • Wczytuje plik tekstowy
  • Liczy i wyświetla liczbę linii
  • Wyświetla pierwszą i ostatnią linię

💡 Podpowiedź: Użyj File.ReadAllLines()

📝 Zadanie 3: Wyszukiwarka w pliku

Napisz program, który:

  • Pobiera od użytkownika szukaną frazę
  • Wczytuje plik i sprawdza które linie zawierają tę frazę
  • Wyświetla numery linii i ich treść

💡 Podpowiedź: linia.Contains(fraza)

⭐ Zadanie 4: Statystyki pliku

Napisz program, który dla podanego pliku wyświetla:

  • Liczbę linii
  • Liczbę słów (podziel po spacjach)
  • Liczbę znaków (bez spacji)
  • Najdłuższą linię

⭐⭐ Zadanie 5: Czytnik CSV

Napisz program, który:

  • Wczytuje plik CSV (np. „osoby.csv”)
  • Pierwszą linię traktuje jako nagłówki
  • Wyświetla dane w formie: „Nagłówek: wartość”
  • Obsługuje błędy (plik nie istnieje, pusty plik)