Do tej pory dane dla naszych programów były wpisywane z klawiatury, a wyniki wypisywane na ekran. Dużo bardziej przydałaby się jednak metoda pamiętania informacji w jakiś trwalszy i łatwiejszy do przekazania programowi sposób. Taka metodą są pliki dyskowe. Pascal potrafi zapisywać i odczytywać zwykłe pliki w systemnie operacyjnym.
Podstawową sprawą w zrozumieniu obsługi plików jest pojęcie typu pliku. Oczywiście z punktu widzenia sysytemu operacujnego wszystkie pliki są podobne - są po prostu bajtami zapisanymi jeden po drugim. Z punktu widzenia programu są jednak zapisanymi danymi, i aby program wiedział, jaki jest rodzaj i struktura tych danych, określa się dla pliku jego typ.
Definicja zmiennej typu plikowego może mieć jedną z poniższych form:
Typ elementów pliku może być dowolny: liczbowy, wyliczeniowy, tablicowy, rekordowy.
Najprostszym typem plików są pliki tekstowe. Pamiętamy w nich tekst można wczytywać w podobny sposób, jak byłby wpisywany przez użytkownika na klawiaturze. Zapisywanie do takiego pliku nie różni się specjalnie od wypisywania tekstu na ekran.
Do plików o określonym typie elementów możemy zapisywać (i odczytywać z nich) tylko zmienne takiego właśnie typu. Żeby nie było niejasności: dowolny plik, istniejący na dysku można otworzyć i próbować czytać jako strukturę elementów dowolnego typu. Co najwyżej otrzymamy bzdury. Oczywiście sensownym wydaje się czytanie z pliku elementów tego samego typu, jakie się w nim zapisało (choć zdarzają się ustępstwa od tej zasady). Znaczy to, że do pliku o zadeklarowanym typie w programie nie można zapisać zmiennej innego typu.
Pliok bez określonego typu umożliwia odczytywanie i zapisywanie jego części "porcjami", zdefiniowanymi przez użytkownika. Jest to sprawa nieco bardziej złożona i zajmiemy się tym troche później.
Przed wykonaniem jakiejkolwiek operacji na pliku, musimy dokonac przypisania nazwy pliku zmiennej plikowej. Dokonuje się tego procedurą:
ZmiennaPlikowa musi być uprzednio zadeklarowaną zmienną typu plikowego, a Nazwa jest nazwą pliku w systemie (może być z pełną lub względną ścieżką). Poniżej podany jest przykład deklarowania zmiennej plikowej
Następnie należy plik otworzyć jednym z poleceń:
Procedury te mają różne znaczenie w zależności od tego, czy mamy do czynienia z plikeim typu Text, czy file of Typ. W przypadku pliku tekstowego Reset otwiera istnijący plik na dysku i pozwala wyłącznie na czytanie z niego. Rewrite tworzy plik nowy plik (a jeżeli plik o przypisanej nazwie był na dysku kasuje jego zawartość) i pozwala jedynie na zapisanie tekstu. Jeżeli mamy do czynienia z plikiem elementów określonego typu, Reset otwiera istniejący plik i pozwala zarówno na czytanie jak i na pisanie w naszym bieżącym położeniu w pliku (na początku znajdujemy się przed pierwszym elementem, po przeczytaniu lub zapisaniu dowolnego zawsze przesuwamy się o jedną pozycje do przodu). Rewrite zaś tworzy nowy plik lub kasuje juz istniejący, pozwalająć także na zapisywanie i czytanie elementów z bieżacego położenia w pliku.
Dla plików tekstowych istnieje jeszcze trzecia metoda otwarcia:
Procedura ta otwiera plik tekstowy w trybie dopisywania na jego końcu.
Pojęcie bieżącego położenia w pliku jest niezwykle istotne. W przeciwieństwie do tablic, w których mieliśmy dostęp do dowolnej komórki, podając jej indeks, pliki są bardziej jak taśma magnetofonowa. W danym momencie mamy dostęp jedynie do bieżącego elementu (czyli następnego po tym, który przeczytaliśmy lub zapisaliśmy ostatnio). W przypadku plików tekstowych możemy jedynie przesuwać się "w przód " pliku, odczytując bądź zapisując kolejne elementy. W przypadku plików typu nie-tekstowego możemy dokonać co prawda "przewinięcia" do przodu bądź do tyłu, ale w dalszym ciągu nie ma możliwości podania po prostu, w którym miejscu należy coś zapisać lub odczytać (choć sami możemy napisać procedury, wykonujące takie operacje).
Po zakończeniu działania z plikiem należy go zamknąć poleceniem:
Do dyspozycji mamy jeszcze bardzo przydatne funkcje i procedury. Dla plików tekstowych przeznaczona jest funkcja:
Zwraca ona wartość True, jeżeli znajdziemy się na końcu wiersza i False w przeciwnym razie. Dla plików tekstowych i nietekstowych bardzo pomocna jest ta funkcja:
Przyjmuje wartość prawdziwą, jeżeli znajdujemy się na końcu pliku, a False - jeżeli nie.
Dla plików typu file of Typ do dyspozycji mamy funkcje:
która określa, na której pozycji w pliku się znajdujemy (czyli, ile elementów pliku jest już "za nami") oraz:
Oblicza ona rozmiar pliku (czyli ile elementów danego typu zawiera). Dostępna jest także procedura:
Przesuwa nas ona do określonego miejsca w pliku. Uzywając procedury Seek oraz funkcji FilePos, należy pamiętać, że elementy pliku są numerowane od 0. Aby więc ustawić się przed pierwszym elementem (a więc na początku pliku), należy użyć procedury: Seek(F,0). Aby udać się do ostaniego elementu pliku - Seek(F, FileSize(F)-1).FilePost(F)=1 oznacza, że kolejnym przeczytanym elementem będzie drugi element pliku.
W celu odczytania elementów z pliku używamy znanych nam już instrukcji:
Pierwsza z nich ma zastosowanie dla dowolnego pliku. Czyta z niego pojedynczy element. Drugiej używa się jedynie w plikach tekstowych. Po przeczytaniu elementu instrukcja powoduje przejście do kolejnego wiersza tekstu. Bardzo podobnie odbywa się zapis do pliku. Do dyspozycji mamy instrukcje:
Pierwsza powoduje zapisanie elementów w pliku dowolnego typu. Druga ma zastosowanie tylko dla plików tekstowych. Powoduje zapisanie elemnetu i przejście do nowego wiersza.
Poniżej napiszemy sobie przykład użycia kilku powyzszych funcji. Napiszemy program, który do pliku tekstowego o nazwie wprow.txt zapisze wprowadzony
przez użytkownika tekst. Zapisywanie powinno zostać zakończone po napotkaniu pustego wiersza.
Czytanie tekstu wpisanego przez użytkownika
będziemy wykonywać w pętli repeat .. until, aż do napotkania pustego wiersza
Napisz program, który wypisze na ekran tekst z utworzonego w poprzednim przykładzie pliku tekstowego o nazwie wprow.txt
Wykorzystaj konstrukcję bardzo często stosowaną dla przejrzenia całego pliku: while not Eof (Plik) do.
powrót