1 Cel ćwiczenia 1
POLITECHNIKA ŚLSKA
w Gliwicach
WYDZIAA INŻYNIERII BIOMEDYCZNEJ
LABORATORIUM
JZYKÓW PROGRAMOWANIA
C# obsługa plików
Opracował: mgr inż. Marcin Rudzki
v.3.00, Gliwice 2010
1 Cel ćwiczenia
Celem ćwiczenia jest zapoznanie studentów z podstawowymi metodami obsługi plików w języku C#. Studenci
zapoznają się ze sposobem użycia klasStreamReaderiStreamWritersłużącymi do obsługi plików tekstowych
orazBinaryReaderiBinaryWritersłużącymi do obsługi plików binarnych.
UWAGA! Od studentów wymaga się, aby przystępując do niniejszego ćwiczenia potrafili samodzielnie obsłu-
giwać środowisko programistyczne Visual Studio w zakresie umożliwiającym pisanie programu, kompilowanie
i uruchamianie napisanego programu oraz jego debugowanie.
2 Materiał obowiązkowy
Wiedza i umiejętności dotyczące materiału zaprezentowanego w tym rozdziale mogą zostać sprawdzone przed la-
boratorium w ramach krótkiego zadania sprawdzającego (pisemnego lub na komputerach).
Omawiane klasy służące do zapisu i odczytu plików tekstowych oraz binarnych, tj.StreamReader,StreamWri-
ter,BinaryReader,BinaryWriter, są zdefiniowane wewnątrz przestrzeni nazwSystem.IO. Dlatego, aby się
nimi w łatwy sposób posługiwać, należy na początku kodu programu umieścić linięusing System.IO;
Zapamiętaj! using System.IO;
2.1 Zapis i odczyt plików tekstowych
Do zapisu plików tekstowych służy klasaStreamWriter. Tworzenie obiektu tej klasy przebiega standardowo
za pomocą operatoranewpołączonego z wywołaniem jednego z wielu możliwych konstruktorów1. Najprostszym
wywołaniem konstruktora jest przekazanie mu pełnej ścieżki dostępu do pliku, który chcemy utworzyć. Takie
wywołanie konstruktora spowoduje, że jeśli plik o takiej nazwie już istnieje, to zostanie on nadpisany, np.:
1 StreamWriter sWriter = new StreamWriter(@"c:\plik.txt");
1
Konstruktory są opisane w osobnej instrukcji laboratoryjnej.
2.1 Zapis i odczyt plików tekstowych 2
Aby nie nadpisywać poprzedniej zawartości pliku, tylko dopisywać nowe dane należy wywołać konstruktor
z dodatkowym argumentem informującym czy do pliku dane mają być dopisywane (true) czy też poprzednia
zawartość pliku ma być zastąpiona nowymi danymi (false).
1 StreamWriter sWriter = new StreamWriter(@"c:\plik.txt", true);
Zapamiętaj! StreamWriter sWriter = new StreamWriter(nazwaPliku);
Mając już otwarty plik do zapisu, można do niego zapisywać dowolny tekst praktycznie tak samo jak na ekran
używając metodyWrite()lubWriteLine(). Przykład zapisu jednej linii tekstu pokazano poniżej:
1 sWriter.WriteLine("Ten tekst zostanie zapisany do pliku.");
Zapamiętaj! sWriter.WriteLine(); sWriter.Write();
Po zakończeniu operacji zapisu należy upewnić się, że wszystkie dane z bufora są zapisane do pliku oraz za-
mknąć plik. Tym celom służą metody Flush() oraz Close(). Niewywołanie metody Close() spowoduje,
że w utworzonym pliku nie będzie widać wpisanej zawartości oraz może on być uznany przez system opera-
cyjny jako w użyciu, tym samym niemożliwa może być jego modyfikacja bądz usunięcie.
Zapamiętaj! sWriter.Close();
Chcąc zapisać dowolne dane (np. liczby), ale w sformatowanej postaci tekstowej, wystarczy wywołać me-
todę Write() lub WriteLine() podobnie jak dla klasy Console przy wyświetlaniu danych na ekran, np.:
sWriter.WriteLine("dana: {0} opis: {1}", zmiennaLiczbowa, zmiennaTekstowa);
Zbierając przedstawione do tej pory fragmenty kodu w jedną całość, otrzymamy najprostszy program zapi-
sujący plik tekstowy.
1 string nazwaPliku = "plik.txt";
2 string napis = "jakis napis";
3 double liczba = 12345.6789;
4 char znak = q ;
5
6 StreamWriter sWriter;
7 sWriter = new StreamWriter(nazwaPliku);
8 sWriter.WriteLine(napis);
9 sWriter.WriteLine(liczba);
10 sWriter.WriteLine(znak);
11 sWriter.WriteLine("{0} {1:F3} {2}", napis, liczba, znak);
12 Console.WriteLine("Do pliku {0} zapisano dane: {1} {2} {3}", nazwaPliku, napis, liczba, znak);
13 sWriter.Flush();
14 sWriter.Close();
Jeśli nie zostanie podana pełna ścieżka dostępu do pliku, to plik jest tworzony w katalogu roboczym pro-
gramu. W przypadku uruchomiania projektu wprost ze środowiska Visual Studio, plik zostanie stworzony w ka-
talogu[Visual Studio projects]/[Nazwa Projektu]/bin/Debug/lub.../bin/Release/.
2.1 Zapis i odczyt plików tekstowych 3
Mając zapisane w pliku tekstowym dane, należałoby być w stanie je odczytać. W tym celu można użyć klasy
StreamReader, która umożliwia odczyt plików tekstowych. Sposób użycia jest praktycznie identyczny, jak klasy
StreamWriter.
Zapamiętaj! StreamReader sReader = new StreamReader(nazwaPliku);
Aby odczytać uprzednio zapisane dane można posłużyć się poniższym kodem:
1 string nazwaPliku = "plik.txt";
2 string napis;
3 double liczba;
4 char znak;
5
6 StreamReader sReader;
7 sReader = new StreamReader(nazwaPliku);
8 napis = sReader.ReadLine();
9 liczba = double.Parse(sReader.ReadLine());
10 znak = char.Parse(sReader.ReadLine());
11 Console.WriteLine("Z pliku {0} odczytano dane: {1} {2} {3}", nazwaPliku, napis, liczba, znak);
12 sReader.Close();
Poniższy listing prezentuje przykładowy sposób zapisu tablicy liczb do pliku tekstowego oraz jej ponowny
odczyt.
1 class Program
2 {
3 static void ZapiszTablice(string nazwaPliku, double[] tablica)
4 {
5 StreamWriter sWriter = new StreamWriter(nazwaPliku);
6 sWriter.WriteLine(tablica.Length); // najpierw zapisac ilosc elementow
7 foreach (double d in tablica) sWriter.WriteLine(d); // potem kazdy element w nowej linii
8 Console.WriteLine("Zapisano do pliku {0}", nazwaPliku);
9 sWriter.Flush();
10 sWriter.Close();
11 }
12
13 static void OdczytajTablice(string nazwaPliku, out double[] tablica)
14 {
15 tablica = null;
16 StreamReader sReader = new StreamReader(nazwaPliku);
17 int ile = int.Parse(sReader.ReadLine()); // najpierw byla zapisana dlugosc tablicy
18 tablica = new double[ile];
19 for (int i = 0; i < ile; i++)
20 tablica[i] = double.Parse(sReader.ReadLine()); // a potem jej elementy
21 Console.WriteLine("Odczytano z pliku {0}", nazwaPliku);
22 sReader.Close();
23 }
24
25 static void Main(string[] args)
26 {
27 Random rnd = new Random();
28 double[] tab = new double[10];
29 for (int i = 0; i < tab.Length; i++) tab[i] = rnd.NextDouble();
30
3 Materiał dodatkowy 4
31 Console.WriteLine("Zawartosc tablicy:");
32 foreach (double d in tab) Console.WriteLine("{0:F5}", d);
33
34 ZapiszTablice("tablica.txt", tab);
35
36 Array.Clear(tab, 0, tab.Length);
37
38 Console.WriteLine("Zawartosc tablicy:");
39 foreach (double d in tab) Console.WriteLine("{0:F5}", d);
40
41 OdczytajTablice("tablica.txt", out tab);
42 Console.WriteLine("Zawartosc tablicy:");
43 foreach (double d in tab) Console.WriteLine("{0:F5}", d);
44
45 Console.ReadKey();
46 }
47 }
Zaleca się samodzielne przestudiowanie powyższego przykładu oraz przetestowanie go w praktyce.
Przy obsłudze plików tekstowych przydatna jest metodaSplit()umożliwiająca dzielenie łańcucha na pod-
łańcuchy. Przerobienie powyższego przykładu tak, aby można było zapisywać i odczytywać tablice dwuwymia-
rowe, przy czym każdy wiersz tablicy ma być zapisany jako wiersz w pliku tekstowym, pozostawia się jako
zadanie do samodzielnego wykonania.
3 Materiał dodatkowy
3.1 KlasaFileStream
KlasaFileStreamumożliwia niskopoziomowy dostęp (zapis i odczyt) do plików wszystkich typów. Niskopozio-
mowy czyli na poziomie pojedynczych bajtów. Za pomocą tej klasy można odczytywać i zapisywać wyłącznie
pojedyncze bajty bądz też bloki bajtów bez jakiejkolwiek ich interpretacji. Z tego powodu operowanie tekstami,
wartościami zmiennych wielobajtowych (jak np.double) jest utrudnione i musiałoby być implementowane od
zera . Jednak do obsługi plików przechowujących tylko wartości zapisane w zmiennej 8-mio bitowej nadaje
się doskonale. KlasaFileStreamjest podstawą, której używają klasy obsługujące różne typy danych takie,
jak poznane jużStreamReaderiStreamWriteroraz przedstawione poniżejBinaryReaderiBinaryWriter.
Konstruktory tych klas można także wywołać z argumentem będącym obiektem klasyFileStream.
Przykład użycia klasyFileStreamdo zapisu i odczytu pliku binarnego przedstawiono poniżej.
1 string nazwaPliku = @"plik.bin";
2 byte liczba;
3
4 FileStream fStream = new FileStream(nazwaPliku, FileMode.Create);
5
6 Console.Write("Ile liczb chcesz podac? ");
7 int ile = int.Parse(Console.ReadLine());
8
9 for ( ; ile > 0; ile--)
10 {
11 Console.Write("Podaj liczbe [0..255]: ");
12 liczba = byte.Parse(Console.ReadLine());
13 fStream.WriteByte(liczba);
3.2 Obsługa dowolnych plików binarnych zapis i odczyt 5
14 // FileStream.WriteByte() potrafi zapisywac TYLKO bajty (liczby 8-mio bitowe)
15 }
16 fStream.Flush();
17 fStream.Close();
18 Console.WriteLine("Zapisano do pliku {0}", nazwaPliku);
19
20 fStream = new FileStream(nazwaPliku, FileMode.Open);
21
22 ile = fStream.Length;
23
24 for (int i = 0; i < ile; i++ )
25 {
26 liczba = fStream.ReadByte();
27 Console.Write(liczba + " ");
28 }
29 fStream.Close();
30
31 Console.WriteLine("\nOdczytano z pliku {0}", nazwaPliku);
32 Console.ReadKey();
Jak widać użycie klasyFileStreamwygląda praktycznie tak samo, jak poznanych już klas obsługujących
pliki tekstowe. Po udanym otwarciu pliku w trybie do zapisu (new FileStream(nazwaPliku,FileMode.Cre-
ate)) następuje zapis pojedynczych bajtów liczb podanych przez użytkownika (fStream.WriteByte(liczba)).
Na koniec następuje synchronizacja bufora (fStream.Flush()) oraz zamknięcie strumienia (fStream.Close()).
Odczyt pliku wygląda podobnie. Po otwarciu pliku do odczytu (new FileStream(nazwaPliku,FileMode.
Open)) następuje odczyt (liczba=fStream.ReadByte()) tylu bajtów, jaka jest długość pliku-strumienia
(fStream.Length) oraz ich wyświetlenie na ekranie. Na koniec za pomocąfStream.Close()następuje za-
mknięcie pliku.
3.2 Obsługa dowolnych plików binarnych zapis i odczyt
Jak już wspomniano, za pomocą klasyFileStreammożliwy jest odczyt oraz zapis dowolnych plików, ale na po-
ziomie pojedynczych bajtów. Aby w łatwy sposób obsługiwać pliki binarne przechowujące wartości dowolnych
typów (np.intczydouble), należy użyć klasBinaryReaderorazBinaryWriter. Stanowią one rozszerzenie
możliwości klasyFileStream.
Poniższe przykłady pokazują, w jaki sposób zapisywać wartości typuintdo pliku binarnego oraz jak pózniej
je odczytać.
1 string nazwaPliku = @"plik.bin";
2 int liczba;
3 int ile;
4
5 FileStream fStream = new FileStream(nazwaPliku,FileMode.Create);
6 BinaryWriter bWriter = new BinaryWriter(fStream);
7
8 Console.Write("Ile liczb chcesz podac? ");
9 ile = int.Parse(Console.ReadLine());
10 for ( ; ile > 0; ile--)
11 {
12 Console.Write("Podaj liczbe calkowita: ");
13 liczba = int.Parse(Console.ReadLine());
14 bWriter.Write(liczba);
3.2 Obsługa dowolnych plików binarnych zapis i odczyt 6
15 }
16 bWriter.Flush();
17 fStream.Flush();
18 bWriter.Close();
19 fStream.Close();
20
21 Console.WriteLine("Zapisano do pliku {0}", nazwaPliku);
22 Console.ReadKey();
Jak łatwo zauważyć, potrzebne są obie klasy, tj.FileStreamdająca dostęp do pliku orazBinaryWriter
umożliwiająca operowanie danymi innych typów, niż tylko bajty. Zapis pliku odbywa tak samo, jak poprzed-
nio, czyli po otwarciu pliku (tym razem tworząc obiekty dwóch klas) następuje zapis wartości za pomocą
bWriter.Write(). Po skończonym zapisie bufory zapisu są synchronizowane oraz następuje zamknięcie pliku.
Odczyt tak stworzonego pliku pokazano poniżej.
1 string nazwaPliku = @"plik.bin";
2 int liczba;
3
4 FileStream fStream = new FileStream(nazwaPliku, FileMode.Open);
5 BinaryReader bReader = new BinaryReader(fStream);
6
7 while (bReader.PeekChar() != -1)
8 {
9 liczba = bReader.ReadInt32();
10 Console.WriteLine(liczba);
11 }
12 bReader.Close();
13 fStream.Close();
14
15 Console.WriteLine("Odczytano z pliku {0}", nazwaPliku);
16 Console.ReadKey();
Wszystko przebiega podobnie jak w poprzednich przykładach, tylko do sprawdzenia, czy wystąpił ko-
niec pliku użyto metodyPeekChar(). Zwraca ona kolejny bajt ze strumienia, lecz nie pobiera go (tzn. nie
zostaje zwiększony wskaznik pliku). Do określenia ile liczb należy odczytać z pliku nie można użyć bezpo-
średniofStream.Lengthgdyż jest to długość pliku w bajtach, a nie w wielokrotności liczb typuint. Klasa
BinaryReaderoferuje wiele metod odczytujących dane, które zebrane zostały w Tab. 1. Pamiętać należy, że
dowolny ciąg bajtów może być interpretowany w różny sposób. To od programisty zależy jak mają zostać in-
terpretowane dane z pliku binarnego. Formalnie nic nie stoi na przeszkodzie, by plik zapisany wartościami typu
doubleodczytać metodąReadChar(), jednak tak odczytane dane z punktu widzenia użytkownika są błędne.
4 Zadania do wykonania przed ćwiczeniem 7
metoda opis
PeekChar() Zwraca kolejny znak ze strumienia ale nie pobiera go.
Read() Pobiera bajt (lub bajty) ze strumienia.
ReadBoolean() Pobiera 1-no bajtową wartość logiczną.
ReadByte() Pobiera 1-no bajtową wartość stałoprzecinkową bez znaku.
ReadBytes() Pobiera określoną liczbę 1-no bajtowych wartości stałoprzecinkowych bez znaku.
ReadChar() Pobiera pojedynczą wartość znakową, zależnie od kodowania może to być 1 lub 2 bajty.
ReadChars() Pobiera określoną liczbę wartości znakowych, uwaga jak powyżej.
ReadDecimal() Pobiera 16-to bajtową wartość numeryczną.
ReadDouble() Pobiera 8-mio bajtową wartość zmiennoprzecinkową.
ReadInt16() Pobiera 2-u bajtową wartość całkowitoliczbową ze znakiem.
ReadInt32() Pobiera 4-ro bajtową wartość całkowitoliczbową ze znakiem.
ReadInt64() Pobiera 8-mio bajtową wartość całkowitoliczbową ze znakiem.
ReadSByte() Pobiera 1-no bajtową wartość całkowitoliczbową ze znakiem.
ReadSingle() Pobiera 4-ro bajtową wartość zmiennoprzecinkową.
ReadString() Pobiera ciąg znaków.
ReadUInt16() Pobiera 2-u bajtową wartość całkowitoliczbową bez znaku.
ReadUInt32() Pobiera 4-ro bajtową wartość całkowitoliczbową bez znaku.
ReadUInt64() Pobiera 8-mio bajtową wartość całkowitoliczbową bez znaku.
Tab. 1: Metody klasyBinaryReadersłużące do odczytu danych
4 Zadania do wykonania przed ćwiczeniem
Zaleca się wykonanie poniższych ćwiczeń przed przystąpieniem do ćwiczenia laboratoryjnego:
1. Napisać program, który w pliku tekstowym zapisze dane o osobie, takie jak: imię, nazwisko, dzień, miesiąc
i rok urodzenia.
2. Zaimplementować funkcje służące do zapisu i odczytu tablic dwuwymiarowych.
3. Za pomocą wyżej zaimplementowanych funkcji wczytać z plików dwie macierze dwuwymiarowe, jeśli to
możliwe wykonać ich dodawanie, wynik zapisać w trzecim pliku tekstowym.
5 Program ćwiczenia
W ramach ćwiczenia laboratoryjnego studenci mają za zadanie napisać programy zadane przez prowadzącego.
Zakres tematyczny pokrywa się z materiałem przedstawionym w niniejszej instrukcji. Zalecane jest, aby studenci
przed laboratorium przećwiczyli we własnym zakresie zaprezentowaną część materiału.
Przed rozpoczęciem laboratorium przewidziane jest sprawdzenie wiedzy i umiejętności2 studentów z nastę-
pujących zagadnień:
1. zapis i odczyt plików tekstowych, uwzględniając konwersję odczytanych danych na poprawne typy,
2. zapis i odczyt plików binarnych (*).
2
czyli tzw. wejściówka, której niezaliczenie powoduje niezaliczenie całego ćwiczenia laboratoryjnego
LITERATURA 8
Literatura
[1] Hejlsberg A., Wiltamuth S., Golde P.; Microsoft C# Language Specification; Addison-Wesley; 2004.
[2] The C# Language;http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
[3] Liberty J. (Tłumaczenie: Walczak T.); C# Programowanie; Helion; 2005.
[4] Lis M.; C# Praktyczny kurs; Helion; 2007.
[5] Portal CentrumXP.pl, kurs C# cz. I oraz cz. II;http://www.centrumxp.pl/dotNET/
[6] Dusiński D; Kurs C# (ver 2.0);http://www.toya.net.pl/~daniel_d/csharp/index.html
[7] http://www.google.pl/
Wyszukiwarka
Podobne podstrony:
9 TurboPascal Obsługa plików w turbo pascaluObsługa plików w Linuxieobsluga plikowNauka Kompresowanie plikówobsługa pojazdu EgzaminDNS ObslugaNazwobsluga wiertarki stolowejRozdział 04 System obsługi przerwań sprzętowychInstrukcja obsługi bankomatu 1Instrukcja obsługi Przenośna uniwersalna ładowarka USB Nokia DC 18Cięcie pliku ac3, Ekspresowe cięcie pliku ac3, Łączenie plików audioinstrukcja obslugi Sagemcom DSI83Instrukcja obsługi alarm Logic CAN LC 5 wyd 1 (2)więcej podobnych podstron