~~NOCACHE~~
~~REVEAL theme=simple&disableLayout=0&transition=none&controls=1&show_progress_bar=1&build_all_lists=0&show_image_borders=0&horizontal_slide_level=2&enlarge_vertical_slide_headers=0&show_slide_details=1&open_in_new_window=1&size=1024x768~~
====== Operacje na plikach ======
===== Plik =====
* plik zawiera ciąg bajtów
* strumień danych - dane w plikach odczytujemy lub zapisujemy **sekwencyjnie**
* nazwa i ścieżka do pliku
* bezwzględna \\ ''C:\Users\Marek\Pulpit\plik.txt''
* względna \\ ''plik.txt'' \\ ''..\Pulpit\plik.jpg''
* przestrzeń nazw ''[[https://learn.microsoft.com/en-us/dotnet/api/system.io?view=net-6.0|System.IO]]'' \\ zawiera klasy i narzędzia do odczytu i zapisu plików (strumieni danych)
===== Operacje na strumieniach =====
* **otwieranie** strumieni: tworzenie plików lub dostęp do istniejących plików
* podstawowa klasa [[https://learn.microsoft.com/en-us/dotnet/api/system.io.filestream?view=net-7.0|FileStream]] niskopoziomowy dostęp do plików \\ Inne: ''MemoryStream'', ''NetworkStream'', ...
* otwieranie w trybie do **odczytu**, **zapisu**, **dodawania**
* strumienie **tekstowe** i **binarne**
* **odczyt** - pobieranie sekwencji danych ze strumienia
* **zapis** - wysyłanie sekwencji danych do strumienia
* **przeszukiwanie** - szukanie i ustawienie aktualnej pozycji w strumieniu
* **zamykanie** strumienia - metoda ''Close()'', brak zamknięcia strumienia może spowodować utratę danych lub uszkodzenie pliku
===== Pliki tekstowe i binarne =====
* ''StreamWriter'' - zapis plików tekstowych
* ''StreamReader'' - odczyt plików tekstowych
* ''BinaryWriter'' - zapis danych binarnych
* ''BinaryReader'' - odczyt danych binarnych
===== StreamReader =====
Otworzenie strumienia do odczytu pliku tekstowego
var reader = new StreamReader("C:\\Users\\Marek\\Pulpit\\plik.txt")
^ Metoda ^ Opis ^
| ReadLine | odczyt linii tekstu |
| Read | odczyt pojedynczego znaku |
| ReadToEnd | odczyt całego pliku |
| Peek | podejrzyj kolejny znak |
| Close | zamknięcie strumienia |
^ Własność ^ Opis ^
| EndOfStream | ''True'', gdy koniec strumienia |
===== Otwieranie pliku =====
// Utworzenie obiektu czytającego z pliku
StreamReader reader = new StreamReader("tekst.txt");
// Tu operacje czytania sekwencji danych
// Zamknięcie strumienia
reader.Close();
===== Ścieżki w systemie Windows =====
Ścieżka **bezwzględna** rozpoczyna się od numeru nośnika
string nazwa_pliku = "C:\\Temp\\work\\test.txt";
To samo z użyciem ''@'', który wyłącza znaki specjalne w łańcuchu
string nazwa_pliku = @"C:\Temp\work\test.txt";
Uwaga na przenośność: unikaj ścieżek bezwzględnych
===== =====
Ścieżka **względna** określana względem katalogu roboczego (bieżącego)
string nazwa_pliku = "test.txt";
string nazwa_pliku2 = "Dokumenty\\tekst.txt";
string nazwa_pliku3 = @"..\..\Dokumenty\tekst.txt";
Katalog roboczy System.IO.Directory.GetCurrentDirectory();
===== Odczyt pliku linia po linii =====
StreamReader reader = new StreamReader(plik);
int i=1;
while(!reader.EndOfStream)
{
string linia = reader.ReadLine() ?? "";
Console.WriteLine("{0} : {1}", i, linia);
}
reader.Close();
===== Instrukcja using =====
**using** automatycznie zamyka strumień i zwalnia wszystkie zasoby po zakończeniu obsługi strumienia
using( obiekt_strumienia )
{
// operacje na strumieniu
}
===== Przykład =====
string plik = "plik.txt";
using(StreamReader reader = new StreamReader(plik))
{
int i=1;
while(!reader.EndOfStream)
{
string linia = reader.ReadLine() ?? "";
Console.WriteLine("{0} : {1}", i, linia);
}
}
===== Obsługa błędów =====
* każda operacja na plikach może zakończyć sie niepowodzeniem, np.: zła ścieżka, brak uprawnień, brak miejsca na nośniku, itp.
* ''using'' - zawsze używaj aby automatycznie zwalniać zasoby
* wyjątki: ''[[https://learn.microsoft.com/en-us/dotnet/api/system.io.ioexception?view=net-7.0|IOException]]'', ''FileNotFoundException'', ''DirectoryNotFoundException'', ...
* ''File.Exists()'' i inne metody sprawdzające system plików
===== Przykład =====
string tekst = "";
try
{
var reader = new StreamReader("plik.txt");
using( reader )
{
tekst = sr.ReadToEnd();
}
}
catch(FileNotFoundException)
{
Console.WriteLine("Nie znaleziono pliku: {0}", plik);
}
catch(IOException)
{
Console.WriteLine("Wystąpił błąd wejścia/wyjścia");
}
===== Ćwiczenie ======
Napisz program, który odczyta sekwencje liczb rzeczywistych zapisanych w pliku tekstowym i wyznaczy sumę, wartość średnią wartość minimalną i wartość maksymalną. \\
Nazwę pliku do odczytu podaje użytkownik na początku działania programu.
Zabezpiecz program przed błędami takimi jak:
* niepoprawna nazwa pliku lub brak dostępu do pliku
* niepoprawny format danych zawartych w pliku. Zakładamy, że plik zawiera w każdej linii jedną liczbę rzeczywistą.
Przykładowy plik wejściowy: {{zajecia:cs:liczby-pl.txt}} lub {{zajecia:cs:liczby-en.txt}}
===== StreamWriter ======
Tworzenie nowego pliku
var writer = new StreamWriter(@"C:\Users\Marek\Pulpit\plik.txt" )
Uwaga: jeśli plik istnieje to aktualna zawartość zostanie skasowana.
Dopisywanie do istniejącego pliku
var writer = new StreamWriter(@"C:\Users\Marek\Pulpit\plik.txt", true )
^ Metoda ^ Opis ^
| Write | zapis łańcucha znakowego |
| WriteLine | zapis łańcucha ze znakiem nowej linii |
| Close | zamknięcie strumienia |
===== Przykład =====
using(var sw = new StreamWriter("plik.txt"))
{
sw.WriteLine("Witaj świecie");
sw.WriteLine("Liczba PI wynosi {0,10:F5}", Math.PI);
}
===== Ćwiczenie =====
Napisz program, który zapisze do pliku tekstowego sekwencję ''K'' liczb wylosowanych spośród liczb całkowitych od 1 do ''N''. Wartości ''K'', ''N'' oraz nazwę pliku podaje użytkownik.
Przydatna klasa [[https://learn.microsoft.com/en-us/dotnet/api/system.random?view=net-7.0|System.Random()]] - generator liczb losowych.
^ Metoda ^ Opis ^
| ''Next()'' | zwraca losową wartość całkowitą dodatnią |
| ''Next(10)'' | zwraca losowa wartość całkowiąa mniejszą niż 10 |
| ''NextDouble()'' | zwraca losową wartość rzeczywistą z zakresu ''[0, 1)'' |
===== Przydatne narzędzia =====
* [[https://learn.microsoft.com/en-us/dotnet/api/system.io.file?view=net-7.0|File]] - udostępnia statyczne metody do tworzenia, kopiowania, usuwania plików oraz funkcje pomocnicze tworzenia obiektów ''FileStream''
* [[https://learn.microsoft.com/en-us/dotnet/api/system.io.fileinfo?view=net-7.0|FileInfo]] - klasa udostępniająca podobne funkcje co File.
* [[https://learn.microsoft.com/en-us/dotnet/api/system.io.directory?view=net-7.0|Directory]] - zestaw metod do tworzenia, przenoszenia i listowania folderów
* [[https://learn.microsoft.com/en-us/dotnet/api/system.io.directoryinfo?view=net-7.0|DirectoryInfo]] - klasa udostępniająca podobne metody co Directory
* [[https://learn.microsoft.com/en-us/dotnet/api/system.io.path?view=net-7.0|Path]] - zestaw metod do operacji na ścieżkach
===== Klasa File =====
^ Metoda ^ Opis ^
| ''Copy, Move, Delete'' | kopiowanie, przenoszenie, usuwanie plików |
| ''CreateText'', ''OpenText'' | Tworzenie i otwieranie plików tekstowych |
| ''ReadAllLines'', ''ReadAllBytes'', ''ReadAllText'' | Odczyt zawartości pliku |
| ''WriteAllLines'', ''WriteAllBytes'', ''WriteAllText'' | Zapis zawartości pliku |
| ''Exists'' | czy wskazany plik istnieje |
===== Klasa Directory =====
^ Metoda ^ Opis ^
| ''CreateDirectory, Move, Delete'' | tworzenie, przenoszenie, usuwanie folderów |
| ''GetFiles'', ''GetDirectories '' | zwraca tablicę nazw plików (podkatalogów) wskazanego folderu |
| ''Exists'' | czy wskazany folder istnieje |
===== BinaryReader =====
Klasa ''[[https://learn.microsoft.com/en-us/dotnet/api/system.io.binaryreader?view=net-6.0|BinaryReader]]'' odczyt wartości w postaci binarnej
^ Metoda ^ Opis ^
| ''Read'' | odczyt sekwencji ''N'' bajtów do tablicy |
| ''ReadInt'', ''ReadChar'', ''ReadDouble'' | Odczyt wartości określonego typu |
Klasa ''[[https://learn.microsoft.com/en-us/dotnet/api/system.io.binarywriter?view=net-6.0|BinaryWriter]]'' zapis wartości w postaci binarnej
^ Metoda ^ Opis ^
| ''Write'' | zapis pojedynczej wartości lub sekwencji ''N'' bajtów z tablicy |
===== Zadanie 6: Odwracanie linii =====
Napisz program, który odwraca kolejność znaków w poszczególnych liniach pewnego pliku tekstowym.
Nazwę pliku podaje użytkownik na początku działania programu.
Jeżeli wskazany plik istnieje to po wykonaniu programu zawartość tego pliku zostaje zamieniona w taki sposób, że każda kolejna linia tekstu posiada odwróconą kolejność znaków.
Przykładowo, jeśli plik zawiera tekst
Ala ma kota
a Ewa ma psa.
to jego zawartośc zamienia się w
atok am alA
.asp am awE a
===== =====
Jeżeli podany przez użytkownika plik nie istnieje lub operacje na plikach nie powiodły się to program wypisuje stosowany komunikat błędu i kończy swoje działanie.
Adres do zadania w Moodle: [[https://moodle.umk.pl/mod/assign/view.php?id=126250]]