~~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]]