Obsługa plików

background image

1 Cel ćwiczenia

1

POLITECHNIKA ŚLĄSKA

w Gliwicach

WYDZIAŁ INŻYNIERII BIOMEDYCZNEJ

LABORATORIUM

JĘZYKÓ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 klas StreamReader i StreamWriter służącymi do obsługi plików tekstowych

oraz BinaryReader i BinaryWriter sł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 nazw System.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 klasa StreamWriter. Tworzenie obiektu tej klasy przebiega standardowo –

za pomocą operatora new połączonego z wywołaniem jednego z wielu możliwych konstruktorów

1

. 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.

background image

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 metody Write() lub WriteLine(). 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ądź 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/.

background image

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

background image

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 metoda Split() 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

Klasa FileStream

Klasa FileStream umoż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ądź 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. Klasa FileStream jest podstawą, której używają klasy obsługujące różne typy danych takie,

jak poznane już StreamReader i StreamWriter oraz przedstawione poniżej BinaryReader i BinaryWriter.

Konstruktory tych klas można także wywołać z argumentem będącym obiektem klasy FileStream.

Przykład użycia klasy FileStream do 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);

background image

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 klasy FileStream wyglą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ą klasy FileStream moż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. int czy double), należy użyć klas BinaryReader oraz BinaryWriter. Stanowią one rozszerzenie

możliwości klasy FileStream.

Poniższe przykłady pokazują, w jaki sposób zapisywać wartości typu int do pliku binarnego oraz jak później

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);

background image

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. FileStream dająca dostęp do pliku oraz BinaryWriter

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 metody PeekChar(). Zwraca ona kolejny bajt ze strumienia, lecz nie pobiera go (tzn. nie

zostaje zwiększony wskaźnik pliku). Do określenia ile liczb należy odczytać z pliku nie można użyć bezpo-

średnio fStream.Length gdyż jest to długość pliku w bajtach, a nie w wielokrotności liczb typu int. Klasa

BinaryReader oferuje 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

double odczytać metodą ReadChar(), jednak tak odczytane dane z punktu widzenia użytkownika są błędne.

background image

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 klasy BinaryReader sł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ści

2

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

background image

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/


Document Outline


Wyszukiwarka

Podobne podstrony:
Obsługa plików w turbo pascalu
Obsługa plików, Programowanie, wykłady C++
Wykład 1, Obsługa plików, Obsługa plików
Obsługa plików w VBA, Akademia Morska Szczecin Nawigacja, uczelnia, ore
Obsługa plików
9 TurboPascal Obsługa plików w turbo pascalu
12 Obsługa plików
Obsługa plików in out
12 Obsługa plików
Trzy dowolne programy do obsługi poczty elektronicznej, formaty plików graficznej
obsluga klienta 1
SO8 Systemy plików
Użytkowanie, Obsługiwanie i Kierowanie Eksploatacją
Formaty plików dźwiękowych
Obsługa interesantów
Piec LSL UB Instrukcja obsługi

więcej podobnych podstron