Kiedy napiszesz np. bazę danych wypadałoby, aby cała
jej zawartość była zapisane gdzieś na dysku. Można by było odczytywać
poszczególne elementy, dopisywać nowe... Bez tego nie można byłoby nazwać
tego programu bazą. Aby utworzyć plik w Pascalu, musisz się zdecydować,
jaka będzie jego zawartość. Może to być zwykły plik tekstowy, składający
się z samych elementów typu word lub np. rekordów. Istnieje jeszcze typ
niezdefiniowany czyli taki, który może naraz zawierać wiele elementów
różnego typu (np. BMP). Taka definicja pliku jest niezbędna, gdyż komputer
musi wiedzieć, jak interpretować zawartość takiego pliku. Rolę pośrednika
między nami, a plikiem pełni pewna zmienna typu odpowiedniego dla danego
pliku, np:
var plik1 :text; {plik tekstowy} plik2 :file of byte; {plik z elementami typu byte}Można tutaj wymyślać naprawdę różne twory. Sama jednak zmienna jest nic nie warta. Musimy ją skojarzyć z odpowiednim zbiorem na dysku. Może to być również plik nieistniejący, jeśli zamierzamy dopiero go utworzyć. Do przypisania zmiennej konkretnego pliku służy procedura ...Od tej pory wszystkie operacje wykonywane na zmiennej plik1, będą wykonywane na pliku auto.bat. Oznacza to, że jeśli chcesz coś zrobić z plikiem, to używasz nazwy zmiennej, a nie nazwy pliku. Ponieważ nasz plik jest tekstowy, więc akurat pasuje do zmiennej plik1. Zanim jednak zaczniemy cokolwiek z nim wyrabiać trzeba ten plik otworzyć. I tutaj sposobów jest kilka. Jeśli, tak jak w naszym przypadku, plik jest tekstowy, to w zależności od potrzeb możesz użyć: rewrite (zmienna) | zostanie utworzony nowiutki, pusty plikJeżeli mamy plik inny niż tekstowy, to stosujemy te same procedury poza append, która dotyczy tylko i wyłącznie plików tekstowych. Jeżeli chodzi o dwie pierwsze instrukcje, to możemy opcjonalnie dodać im drugi parametr, który określa rozmiar tworzonych zapisów. Jest to ważne szczególnie przy plikach niezdefiniowanych, gdyż wtedy domyślnie ustawiana jest wartość 128, co oznacza, że każdy zapis miałby długość 128 bajtów (byłoby to bardzo niepożądane). Do zapisu i odczytu stosujemy standardowe procedury read i write (w przypadku plików tekstowych również readln i writeln), spróbujmy zatem rozgryźć naszego autoexeca: program showfile;Widać jak na dłoni, że aby odczytać z pliku jakąś wartość to jako pierwszy parametr procedury read (tutaj readln) podajemy zmienną charakteryzującą plik. I to jest cała filozofia. Funkcja eof (end of file) sprawdza czy kursor jest na końcu pliku i jeśli, to zwraca wartość true. Na końcu programu zawsze powinno się zamykać pliki. Służy do tego procedura close (ostatni wiersz). Ten programik odczytywał poszczególne linijki pliku, ale można też (mowa cały czas o plikach wyłącznie tekstowych) odczytywać po kawałku, np. literami: ...lub kilkuliterowymi porcjami: ...Jednak nasze rozwiązanie wydaje się najrozsądniejsze, gdyż nie trzeba dodatkowo sprawdzać, czy kursor jest na końcu linijki i czy trzeba przejść do następnego wiersza. Problem ten nie występuje w plikach nietekstowych gdyż nie wyróżniamy w nich linijek (wszystko jest zapisane jakby w jednej), dlatego też nie możemy stosować readln'ów i writeln'ów. Oprócz znaków z plików tekstowych można również wyciągnąć liczby. Załóżmy, że w pierwszej linijce mamy jakąś liczbę z przedziału 0-65535: var liczba : word;Na pewno zadziała. Jeśli byłoby nawet kilka liczb w tej samej linijce (pooddzielanych spacjami) to moglibyśmy je odczytywać do bólu i też by działało. A jak ma się sprawa z plikami innych typów (w końcu tekstowe odstawiamy na bok)? Też jest banalna. Załóżmy przykładową książkę telefoniczną:Chyba jasne. Jeżeli byśmy chcieli odczytać od razu drugi rekord to posłużylibyśmy się instrukcją seek: ...Drugi parametr to numer elementu w pliku przy czym elementy są numerowane od zera. A jak dopisać do bazy jeszcze jedną osobę? Append odpada. Wystarczy jednak znać funkcję filesize, która zwraca rozmiar pliku (czyli ilość jego elementów). Dzięki temu możemy zastosować taki chwyt: ...I już! To może zastąpić nam append.. Najgorzej jest z plikami niezdefiniowanymi (po prostu file). Tutaj do zapisu i odczytu stosuje się procedury blockread i blockwrite, a przy otwieraniu takich plików trzeba też pamiętać aby do procedury np. reset dodać drugi parametr, o którym wspominałem na początku (na razie wystarczy jak podamy 1). Wtedy: blockread (plik,x,size) do zmiennej x wczyta taką porcję danych określiliśmy parametrem size (zazwyczaj jest to rozmiar zmiennej x). Blockwrite podlega tym samym zasadom. Bardziej szczegółowo przyjrzymy się tym instrukcjom przy innej okazji. Na koniec wspomnę jeszcze tylko o kliku instrukcjach, które się przydają: filepos (zmienna) | zwraca pozycję kursora w plikuJest tego trochę, ale chyba niezbyt to trudne. Zapis do pliku uses crt; var i:word; plik:text; begin clrscr; assign(plik,'c:\tp\pliki\dane.txt'); rewrite(plik); randomize; for i:=1 to 1000 do begin append(plik); writeln(plik,random(1000)+1); end; close(plik); end. odczyt z jednego i zapis do drugiego pliku uses crt; var liczba:word; p1,p2:text; begin clrscr; assign(p1,'c:\tp\pliki\dane.txt'); assign(p2,'c:\tp\pliki\wynik.txt'); reset(p1); rewrite(p2); repeat readln(p1,liczba); if liczba mod 2=0 then begin append(p2); writeln(p2,liczba); end; until eof (p1); close(p1); close(p2); end. |