09 Pliki cwiczenia przygotowujace

background image

IX.

Zbiory danych

Aplikacje utworzone w poprzednich ćwiczeniach traktowały użytkownika jako źródło danych. Uj-

mując zagadnienie dokładniej, danymi były ciągi znaków odczytywane przez aplikację z klawiatury

konsoli. Wyniki wyprowadzane były na monitor konsoli. W obu przypadkach dane i wyniki miały po -

stać tekstu. Klawiatura występuje zatem jako źródło danych, a monitor jako zbiór wyników.

W rzeczywistości zbiory utworzone przez ludzi, a zawierające informacje, są traktowane jako

zbiory danych, które po przetworzeniu w określony sposób stają się wynikami. Zachowane w trwałej

postaci mogą być zbiorami danych dla kolejnych procesów przetwarzania.

Aby wyniki wyprowadzone na ekran stały się trwałym zbiorem danych aplikacja musi wykorzy-

stać odpowiednią metodę w celu ich zachowania. W przeciwnym przypadku użytkownik musiałby

każdorazowo uruchamiać aplikację generującą wyniki, aby móc je wykorzystać w innym procesie.

Język Visual Basic 2010 pozwala tworzyć zbiory danych, które przechowywane są na różnego

rodzaju nośnikach informacji. Dane mogą być następnie odczytane ze zbioru i przetworzone, a ope -

rację taką można wykonać wielokrotnie.

Tak, jak każda informacja – kod źródłowy projektu, ikona, grafika wektorowa, audycja dźwięko-

wa, dokument tekstowy – dane przechowywane w zbiorze na nośniku, to ciągi liczb. O tym, co przed-

stawiają liczby przechowywane w pliku, zadecyduje sposób ich interpretacji. Wiele aplikacji, przy

podjętej przez użytkownika próbie otwarcia pliku, dokonuje sprawdzenia, czy otwierany plik zawiera

dane, które przez aplikację mogą być interpretowane. Przykładowo, próba otwarcia w edytorze tek-

stowym pliku przechowującego obrazy w formacie JPEG skutkować będzie (w najlepszym przypad-

ku) prośbą do użytkownika o wskazanie właściwej strony kodowej. Natomiast przeglądarka interneto-

wa wyświetli obraz zapisany w pliku.

Visual Basic 2010 realizuje dostęp do plików na trzy sposoby:

sekwencyjny (ang. sequential),

swobodny (random),

binarny (binary).

Dostęp sekwencyjny stosuje się do przetwarzania plików zawierających informacje w postaci

tekstowej. Przetwarzanie plików tekstowych stanowi treść następnego punktu.

IX.1.

Pliki tekstowe

Pliki tekstowe zawierają ciągi znaków reprezentujących litery, cyfry oraz inne dostępne znaki,

a także znaki sterujące takie, jak np. znaki końca wiersza. W takim kontekście plik tekstowy przypo -

mina konsolę z jej urządzeniem wejściowym (np. klawiaturą) i wyjściowym (np. monitorem). Każdy,

kto korzystał z edytora plików tekstowych, ma świadomość, że plik taki można dowolnie edytować.

Jednak zapis danych do takiego pliku, lub odczyt z pliku tekstowego podlega ograniczeniom dostępu

background image

sekwencyjnego. Oznacza to, że zapis informacji może być realizowany jedynie w pozycji końcowej,

która przemieszcza się wraz z ilością zapisanych danych. Odczyt może być realizowany tylko od po-

czątku pliku. Po odczytaniu pewnej ilości informacji punkt odczytu przesuwa się i odczytane dane nie

mogą być odczytane ponownie. Należy przez to rozumieć, że aby odczytać pewną informację zawar-

tą w określonym miejscu pliku przetwarzanego sekwencyjnie trzeba odczytać wszystkie informacje

poprzedzające i dopiero wtedy pobrać informację potrzebną.

Problemem zasadniczym jest utworzenie zbioru z danymi. Sekwencja działań w tym zakresie

jest następująca:

utworzenie pliku i otwarcie go w celu wyprowadzenia do niego informacji,

wyprowadzenie do pliku informacji,

zamknięcie pliku.

Pierwsze działanie realizowane jest w Visual Basic 2010 poprzez procedurę FileOpen, która

zdefiniowana jest w module FileSystem przestrzeni nazw Microsoft.VisualBasic. Moduł FileSystem

zawiera metody przydatne przy operacjach na systemie plików. Chwilowo pominiemy działanie pole-

gające na wyprowadzaniu informacji do otwartego pliku. Natomiast zamknięcie pliku wykonuje się

używając procedury FileClose zdefiniowanej również w module FileSystem. Każdy otwarty plik po-

winien zostać zamknięty. Ponadto przed zmianą kierunku – zapis

odczyt – konieczne jest za-

mknięcie pliku.

Procedura FileOpen posiada sześć parametrów, z których ostatnie trzy są opcjonalne. Pierw-

szy z wymaganych parametrów oznacza numer przydzielony przez aplikację otwieranemu plikowi

i jest typu Integer. Drugi, typu String, to nazwa otwieranego pliku, może to być dowolne wyrażenie,

którego wynikiem jest łańcuch tekstowy przedstawiający ścieżkę do pliku. Może zawierać literę napę-

du oraz nazwy katalogów. Musi zawierać nazwę pliku.

Trzeci parametr, typu OpenMode, określa tryb w jakim plik jest otwierany. Enumeracja OpenMo-

de zawiera pięć stałych:

Input o wartości 1,

Output – 2,

Random – 4,

Apend – 8,

Binary – 32.

Procedura FileClose pozwala na zamknięcie pojedynczego pliku, o numerze przydzielonym

przez procedurę FileOpen, wybranych plików, lub wszystkich otwartych plików. Najprostszym przy-

padkiem jest ostatni. Aby zamknąć wszystkie otwarte pliki należy wywołać procedurę bez parame-

trów. Aby zamknąć plik o określonym numerze, należy podać jego numer jako parametr. W końcu,

background image

aby zamknąć pliki o wybranych numerach, należy jako parametr podać tablicę o komórkach typu In -

teger zawierających numery plików przeznaczonych do zamknięcia. Kolejne ćwiczenie polegać bę-

dzie na utworzeniu pliku tekstowego w katalogu bin\Debug projektu.

Ćwiczenie 109
Utworzyć w katalogu bin\Debug projektu plik tekstowy.

1. Utwórz projekt aplikacji konsolowej.

2. Zaprogramuj w procedurze Main utworzenie i otwarcie pliku Test.txt, w tym celu użyj pro-

cedury FileOpen z parametrami:

1 – numer przydzielany otwieranemu plikowi,

"Test.txt" – nazwa tworzonego pliku, pominięcie litery napędu i nazw katalogów ozna-

cza, że plik ma zostać utworzony w katalogu aplikacji, która go tworzy, zatem plik po-

wstanie w katalogu bin\Debug projektu,

OpenMode.Output – stała określająca kierunek przemieszczania danych; Output

oznacza wyprowadzanie danych z aplikacji do pliku, Input – kierunek odwrotny.

Przykład.

FileOpen(1, "Test.txt", OpenMode.Output)

3. Zaprogramuj zamknięcie pliku o numerze 1, w tym celu użyj procedury FileClose, poda-

jąc jako parametr numer pliku przydzielony przez procedurę FileOpen.

Przykład.

FileClose(1)

4. Uruchom aplikację i sprawdź po jej zakończeniu, czy w katalogu bin\Debug pojawił się

plik tekstowy.

Utworzony plik jest pusty. Plik posłuży do wykazania, że procedura FileOpen, której trzeci pa-

rametr ma wartość OpenMode.Output, tworzy plik. Oznacza to, że jeśli istnieje plik, o nazwie podanej

jako drugi parametr, to zostanie on zastąpiony nowym o takiej samej nazwie. Zatem, jeśli plik zawie-

rał informacje, to zostaną one utracone. W kolejnym ćwiczeniu w pliku zostaną umieszczone informa-

cje. Zostaną one utracone w wyniku działania aplikacji.

Ćwiczenie 110
Sprawdzić, że tworzony plik zastępuje istniejący plik o określonej nazwie.

1. Wprowadź do pliku Test.txt tekst „Ten tekst zostanie utracony.” używając dowolnego edy-

tora tekstowego (najefektywniej będzie wykorzystać do tego celu edytor tekstowy zinte-

growany ze środowiskiem Visual Studio 2010).

2. Uruchom aplikację utworzoną w ćwiczeniu 100.

background image

3. Sprawdź zawartość pliku Test.txt.

Uwaga. Osoby, które skorzystały z edytora Visual Studio, aby wprowadzić tekst do pliku Test.txt,

po wykonaniu aplikacji, otrzymają komunikat o tym, że plik został zmodyfikowany poza edytorem.

Okno zawiera również pytanie, czy załadować plik ponownie. Należy wybrać przycisk Yes.

Fakt potwierdzony w ćwiczeniu 110. powinien wywołać następującą refleksję – tworzenie pliku

musi być zaprogramowane w taki sposób, aby nie powodowało przypadkowej utraty danych.

Umiemy już utworzyć plik tekstowy. Po wywołaniu procedury FileOpen z parametrami, jak

w ćwiczeniu 109. aplikacja może zapisywać teksty do otwartego pliku Test.txt. Służą do tego nastę-

pujące metody:

Print,

PrintLine,

Write,

WriteLine.

Procedura Print wymaga aby jej pierwszym parametrem była liczba typu

Integer

określająca

numer pliku otwartego przez procedurę FileOpen. Kolejne (opcjonalne) parametry to wyrażenia,

których wartość ma być zapisana w pliku tekstowym. Teksty reprezentujące zapisywane wartości roz-

mieszczane są w ten sposób, że pierwszy znak wyprowadzany jest na kolejnej pozycji tabulatora.

Kolejne ćwiczenie będzie ilustracją wykorzystania procedury Print.

Ćwiczenie 111
Wykorzystać procedurę Print w celu wyprowadzenia do pliku danych użytkownika.

1. Zadeklaruj w części deklaracyjnej modułu zmienne strImię i strNazwisko typu String oraz

zmienną intWiek typu Integer.

2. Zaprogramuj, na początku procedury Main, pobranie od użytkownika imienia, nazwiska

oraz liczby lat i przypisanie ich odpowiednim zmiennym.

3. Utwórz pusty wiersz pomiędzy instrukcjami FileOpen i FileClose i umieść w nim kursor

tekstowy.

4. Zaprogramuj wyprowadzenie do otwartego pliku tekstu „Imię użytkownika to:”, w tym celu

wpisz nazwę procedury Print, a jako parametry podaj:

1 – numer pliku otwartego przez procedurę FileOpen,

"Imię użytkownika to:" – tekst wyprowadzany do pliku.

Przykład.

Print(1, "Imię użytkownika to:")

background image

5. Zaprogramuj wyprowadzenie do pliku wartości zmiennej strImię.

Przykład.

Print(1, strImię)

6. Zaprogramuj wyprowadzenie do pliku wartości zmiennej strNazwisko poprzedzonej tek-

stem „Nazwisko użytkownika to:”, w tym celu użyj wymaganego tekstu jako drugiego pa-

rametru procedury Print, a zmiennej strNazwisko jako trzeciego parametru.

Przykład.

Print(1, "Nazwisko użytkownika to:", strNazwisko)

7. Zaprogramuj wyprowadzenie do pliku wartości zmiennej intWiek poprzedzonej tekstem

„Użytkownik ma lat:”.

8. Uruchom aplikację

9. Otwórz w edytorze środowiska plik Test.txt (menu File, grupa poleceń Open, polecenie

File). Jeśli plik był otwarty, to powtórzy się sytuacja opisana w uwadze poniżej ćwicze-

nia 110.

Zawartość pliku może wyglądać następująco:

Imię użytkownika to:KażdosławNazwisko użytkownika to: OgólnyUżytkownik ma lat: 18

Łatwo zauważyć, że kolejne instrukcje Print wyprowadzają tekst w tym miejscu, w którym za-

kończyło się poprzednie wyprowadzanie. Natomiast wartości kolejnych parametrów procedury Print

wyprowadzane są w odstępie tabulatora. Działanie procedury PrintLine różni się tym, że po za-

kończeniu wyprowadzania ostatniego argumentu, wyprowadzane są znaki końca wiersza. Zostanie

to zilustrowane w kolejnym ćwiczeniu.

Ćwiczenie 112
Sprawdzić działanie instrukcji PrintLine.

1. Dodaj pusty wiersz po ostatniej instrukcji Print.

2. Zaprogramuj wyprowadzenie do pliku pustego wiersza, w tym celu użyj procedury Prin-

tLine podając jedynie numer pliku, do którego wiersz ma zostać wyprowadzony.

Przykład.

PrintLine(1)

3. Skopiuj wszystkie instrukcje Print i wklej ich kopię poniżej instrukcji PrintLine.

4. Zastąp każdą instrukcję Print, we wklejonych wierszach, instrukcją PrintLine.

5. Uruchom aplikację, a po jej zakończeniu sprawdź zawartość pliku Test.txt.

background image

Zawartość pliku może wyglądać następująco:

Imię użytkownika to:KażdosławNazwisko użytkownika to: OgólnyUżytkownik ma lat: 18
Imię użytkownika to:
Każdosław
Nazwisko użytkownika to: Ogólny
Użytkownik ma lat: 18

Dziwić może położenie liczby 18 (przesunięta o jeden znak w prawo w stosunku do słowa

„Ogólny”). Przesunięcie spowodowane jest uwzględnieniem miejsca na znak liczby.

Przed wykonaniem kolejnego ćwiczenia należy połączyć w jedną procedury PrintLine wyprowa-

dzające do pliku tekst „Imię użytkownika to:” oraz wartość zmiennej strImię.

Istnieją dwie funkcje SPC oraz TAB przydatne do ustalania położenia kolejnych tekstów wypro-

wadzanych do pliku. Funkcja SPC generuje tekst składający się ze spacji. Liczba spacji zależna jest

od wartości argumentu funkcji. Funkcja TAB generuje tabulator przenoszący wyprowadzanie tekstu

do kolumny o numerze zależnym od wartości argumentu funkcji, jeśli argument zostanie pominięty, to

tekst przesuwany jest do następnej strefy tabulatora. Kolejne ćwiczenie pokazuje wykorzystanie obu

funkcji.

Ćwiczenie 113
Wykorzystać funkcje SPC oraz TAB do rozłożenia tekstu w pliku.

1. Dodaj, jako drugi parametr procedur PrintLine wywołanie funkcji SPC generującej 5 spa-

cji.

Przykład.

PrintLine(1, SPC(5), "Imię użytkownika to:", strImię)

2. Dodaj jako czwarty parametr wywołanie funkcji TAB generującej tabulator przesuwający

tekst do czterdziestej kolumny.

Przykład.

PrintLine(1, SPC(5), "Imię użytkownika to:", TAB(40), strImię)

3. Uruchom aplikację, a po jej zakończeniu sprawdź zawartość pliku Test.txt.

Zawartość pliku może wyglądać następująco:

Imię użytkownika to:KażdosławNazwisko użytkownika to: OgólnyUżytkownik ma lat: 18
Imię użytkownika to: Każdosław
Nazwisko użytkownika to: Ogólny
Użytkownik ma lat: 18

Należy pamiętać, aby szerokości uzyskiwanych kolumn tekstu były wystarczające do pomiesz-

czenia w nich wyprowadzanych tekstów.

background image

Łańcuchy tekstowe zawarte w wierszach pliku mogą powstawać w wyniku różnych działań apli-

kacji. Przykładowo, treść drugiego wiersza mogła powstać jako efekt instrukcji:

PrintLine(1, " Imię użytkownika to:", TAB(40), strImię)

albo

PrintLine(1, " Imię użytkownika to: Każdosław")

Jeśli zależy nam na tym, aby możliwa była identyfikacja poszczególnych elementów wyprowa-

dzanych do pliku, powinniśmy użyć procedur Write lub WriteLine. Wywołania obu procedur wy-

magają identycznych parametrów jak Print lub PrintLine. Ponieważ różnica pomiędzy działa-

niem procedury Write i WriteLine polega jedynie na wyprowadzaniu przez drugą z nich znaków

końca wiersza, omówione zostanie działanie tylko pierwszej z nich. Wcześniej poczynimy pewne za-

łożenia. Niech wywołanie ma postać:

Write(NumerPliku, strImię, intWiek)

i dodatkowo strImię jest zmienną typu

String

, a intWiek typu

Integer

. Procedura Write wyprowadza

reprezentacje tekstowe parametrów do pliku rozdzielając je przecinkami. Dodatkowo teksty wyprowa-

dzane są w cudzysłowie. Taki tryb działania pozwala w łatwy sposób zinterpretować zawartość pliku

– przecinek oznacza koniec dodanej treści, a jeśli jest ona objęta cudzysłowem, to znaczy, że była

tekstem. Ponieważ znaki końca wiersza jednoznacznie wskazują miejsce zakończenia danych, to po

wyprowadzeniu ostatniego parametru procedura WriteLine nie dodaje przecinka. Kolejne ćwicze-

nie pokazuje działanie procedur Write i WriteLine.

Ćwiczenie 114
Zapoznać się ze sposobem działania procedur Write i WriteLine.

1. Dodaj przed instrukcją FileClose kopię wszystkich wierszy wywołujących procedury Print

(PrintLine) i zamień wszystkie wystąpienia słowa „Print” w kopiach na słowo „Write”.

2. Uruchom aplikację i po jej zakończeniu sprawdź zawartość pliku Test.txt.

Zawartość pliku może być podobna do przedstawionej na rysunku:

Imię użytkownika to:KażdosławNazwisko użytkownika to: OgólnyUżytkownik ma lat: 18
Imię użytkownika to: Każdosław
Nazwisko użytkownika to: Ogólny
Użytkownik ma lat: 18
"Imię użytkownika to:","Każdosław","Nazwisko użytkownika to:","Ogólny","Użytkownik ma

lat:",18,
"Imię użytkownika to:", ,"Każdosław"
"Nazwisko użytkownika to:","Ogólny"
"Użytkownik ma lat:",18

Widać wyraźnie różnicę pomiędzy działaniem procedur Print (PrintLine) i Write

(WriteLine). Każdy tekst objęty jest cudzysłowem. Procedura Write dodaje przecinek po każdym

parametrze, a procedura WriteLine nie dodaje przecinka po ostatnim parametrze.

background image

Umiemy już utworzyć plik tekstowy i zapisać w nim informacje. Mogą być one następnie odczy-

tywane przez inny (lub ten sam) program w celu przetworzenia. Istotne jest przyswojenie sposobu

działania procedur Print i Write. Można oczywiście zastąpić każdą z nich tą drugą, ale będzie to

wymagało dodatkowego nakładu pracy. Generalnie należy się kierować następującą zasadą – jeśli

analizę treści pliku będzie realizować program, to należy korzystać z procedur Write, gdyż ułatwiają

interpretację. W przypadku gdy treść odczytana z pliku będzie interpretowana przez użytkownika,

można posłużyć się procedurami Print.

Przed przystąpieniem do ćwiczeń dotyczących odczytu informacji z pliku tekstowego wykonamy

ćwiczenie przygotowujące dwa pliki przeznaczone do odczytu przez różne procedury.

Ćwiczenie 115
Przygotować dwa pliki przy użyciu procedur Print i Write.

1. Utwórz projekt aplikacji konsolowej.

2. Zadeklaruj w procedurze Main zmienną strTekst typu String.

3. Zaprogramuj:

utworzenie pliku o nazwie PrintTest.txt i otwarcie go w trybie OpenMode.Output,

pętlę For wykonywaną 5 razy, a w niej:

pobranie od użytkownika dowolnego tekstu i przypisanie go zmiennej strTekst,

wyprowadzenie wartości zmiennej strTekst do pliku przy użyciu procedury PrintLi-

ne;

zamknięcie (po zakończeniu pętli) pliku PrintTest.txt.

4. Zadeklaruj zmienną intLiczba typu Integer.

5. Zaprogramuj:

utworzenie pliku o nazwie WriteTest.txt i otwarcie go w trybie OpenMode.Output,

pętlę For wykonywaną 5 razy, a w niej:

przypisanie zmiennej strTekst tekstu „Liczba nr #”, gdzie znak # należy zastąpić

wartością zmiennej sterującej pętlą,

pobranie od użytkownika liczby całkowitej i przypisanie jej zmiennej intLiczba,

wyprowadzenie wartości zmiennych strTekst i intLiczba do pliku przy użyciu proce-

dury WriteLine;

zamknięcie (po zakończeniu pętli) pliku WriteTest.txt.

6. Uruchom program, a po jego zakończeniu sprawdź treść obu plików.

background image

Po wykonaniu aplikacji, której przykładowe działanie przedstawiono na rysunku:

pliki powinny zawierać informacje w postaci przedstawionej na kolejnych dwóch rysunkach.

Plik PrintTest.txt:

Dowolny text
Ala ma kota.
Ola ma psa.
Pies Oli nie lubi kota Ali.
Ala lubi Olę.

Plik WriteTest.txt:

"Liczba nr 1",1
"Liczba nr 2",3
"Liczba nr 3",5
"Liczba nr 4",7
"Liczba nr 5",9

Do odczytu informacji z pliku tekstowego służą metody:

InputString,

LineInput,

Input.

Aby możliwy był odczyt z pliku konieczne jest otwarcie go w trybie do odczytu – OpenMode.In-

put. Zostało to już wcześniej zasygnalizowane, ale powtórzmy – aby zmienić tryb, w którym plik zo-

stał otwarty, należy go zamknąć, a następnie otworzyć w żądanym trybie. Instrukcja otwierająca plik

w trybie do odczytu może mieć następującą postać:

FileOpen(intNumerPliku, strNazwaPliku, OpenMode.Intput)

Procedura FileOpen otwierając plik w trybie Input nie tworzy nowego pliku (jak w trybie Out-

put). Pociąga to za sobą konieczność podania nazwy istniejącego pliku. Jeśli plik o podanej nazwie

nie istnieje wystąpi błąd. Kolejny raz istotne wydaje się sprawdzenie przed użyciem procedury

FileOpen faktu istnienia pliku o podanej nazwie.

Rysunek 48: Projekt_115 w działaniu.

background image

Z otwartego w trybie Input pliku można pobierać dane. Po zakończeniu pobierania danych plik

należy zamknąć używając procedury FileClose.

Funkcja InputString posiada dwa parametry. Pierwszy, to numer pliku otwartego w trybie In-

put. Drugi, określa liczbę znaków, które należy odczytać z pliku. Działanie funkcji przedstawia kolejne

ćwiczenie.

Ćwiczenie 116
Wykorzystać funkcję InputString do odczytu z pliku łańcucha znaków o określonej
długości.

1. Utwórz projekt aplikacji konsolowej i zapisz go (File\Save All). Wymuszenie zapisu pro-

jektu ma na celu utworzenie katalogu projektu, do którego będzie można skopiować pliki.

2. Skopiuj do katalogu bin\Debug projektu pliki PrintTest.txt oraz WriteTest.txt utworzone

przez aplikację wykonaną w poprzednim ćwiczeniu.

3. Zaprogramuj:

otwarcie pliku PrintTest.txt w trybie do odczytu,

Przykład.

FileOpen(1, "PrintTest.txt", OpenMode.Input)

wyświetlenie w konsoli pierwszych 15 znaków odczytanych z pliku przez funkcję In-

putString,

Przykład.

Console.WriteLine(InputString(1, 15))

zamknięcie pliku.

4. Uruchom aplikację i przelicz znaki wyświetlone w konsoli.

Przykładowy efekt działania aplikacji przedstawia rysunek:

Łącznie ze spacjami, w konsoli pojawiło się 13 znaków. Brakujące dwa znaki, to znaki sterujące.

Pierwszy z nich (#13) to polecenie powrotu kursora do pierwszej kolumny. Ze względów historycz-

nych znak ten nazywa się „powrót karetki” (ang. carriage return) – karetka, to część maszyny do pi-

sania przenosząca papier pod głowicą drukującą (lub młoteczkami), a w drukarkach z ruchomą głowi-

cą – część przenosząca głowicę. Drugi znak (#10), to polecenie wciągnięcia papieru o linię (ang. line

Rysunek 49: Projekt_116 w działaniu.

background image

feed). Połączenie tych dwóch znaków sterujących jest jednoznaczne z przejściem do początku nowe-

go wiersza. Widać zatem, że liczba wczytanych z pliku znaków rzeczywiście wynosi 15.

Funkcja LineInput, której wynik jest typu

String

, wymaga tylko jednego parametru – numeru

otwartego pliku, z którego ma nastąpić odczyt. Funkcja odczytuje z pliku tekst aż do napotkania zna-

ków końca wiersza (#13#10), co kończy odczyt. Odczytane znaki (bez znaków końca wiersza) zwra-

cane są jako wynik funkcji. Obrazuje to kolejne ćwiczenie.

Ćwiczenie 117
Zapoznać się z działaniem funkcji LineInput.

1. Dodaj pusty wiersz po instrukcji zamykającej plik.

2. Zadeklaruj w dodanym wierszy zmienną strTeksty typu String o wartość początkowej ″″.

3. Zaprogramuj:

otwarcie pliku PrintTest.txt w trybie do odczytu,

pętlę For wykonywaną pięciokrotnie, a w niej odczyt wiersza znaków z otwartego pli-

ku i dołączenie odczytanych znaków do zmiennej strTeksty,

Przykład.

strTeksty &= LineInput(1)

zamknięcie pliku (po zakończeniu pętli).

4. Wyświetlenie wartości zmiennej strTeksty w konsoli.

5. Uruchom aplikację.

Przykładowe działanie aplikacji przedstawia rysunek:

Teksty kolejnych wierszy zapisanych w pliku tworzą jeden wiersz ze względu na działanie funk-

cji InputLine, która zwraca jedynie treść wiersza bez znaków, które go kończą. Znaki te można do-

łączyć do zmiennej strTeksty posługując się stałą vbCrLf zdefiniowaną w module Constants.

Przykład.

strTeksty &= LineInput(1) & vbCrLf

Procedura Input działa odmiennie niż funkcje InputString i LineInput. Posiada ona dwa

parametry. Pierwszy, jak zwykle, oznacza numer pliku otwartego do odczytu. Drugi jest zmienną, któ-

rej zostanie przypisana wartość odczytana z pliku. Procedura interpretuje odczytywane informacje

Rysunek 50: Projekt_116 po modyfikacji.

background image

zgodnie z typem zmiennej, która jest drugim parametrem, w związku z tym jest szczególnie przydat -

na do wprowadzania danych z plików utworzonych przez procedury Write. Działanie procedury In-

put ilustruje kolejne ćwiczenie.

Ćwiczenie 118
Zapoznać się z działaniem procedury Input.

1. Dodaj przed końcem procedury Main pusty wiersz.

2. Zadeklaruj zmienną strTekst typu String o wartości początkowej ″″ i zmienną intLiczba

typu Integer.

3. Zaprogramuj:

otwarcie pliku WriteTest.txt w trybie do odczytu,

pętlę For wykonywaną pięciokrotnie, a w niej:

odczyt z otwartego pliku (wykorzystaj procedurę Input):

tekstu i przypisanie go zmiennej strTekst,

liczby i przypisanie jej zmiennej intLiczba;

wyświetlenie w konsoli wartości zmiennych strTekst i intLiczba połączonych łańcu-

chem znaków „ to ”;

zamknięcie pliku (po zakończeniu pętli).

4. Uruchom aplikację.

Przykładowy efekt działania aplikacji może być następujący:

Procedura odczytuje dane aż do napotkania przecinka, lub znaków końca wiersza. Odczytany

tekst interpretowanych jest zgodnie z typem zmiennej, której ma być przypisany. Jeśli jest to zmienna

typu liczbowego, to tekst konwertowany jest na liczbę. Należy przykładać szczególną uwagę do fak -

tu, że przecinek jest separatorem danych. Jeśli w pliku zostanie zapisana liczba rzeczywista, a zna -

kiem rozdzielającym część całkowitą od ułamkowej będzie przecinek, to podczas odczytu przez pro-

cedurę Input zostanie odczytana najpierw część przed przecinkiem (jako jedna informacja), a przy

Rysunek 51: Projekt_116 po kolejnej modyfikacji.

background image

drugim odczycie część ułamkowa (jako kolejna informacja). Należy pamiętać, aby liczby rzeczywiste

zapisywane były z kropką dziesiętną, a nie z przecinkiem.

W zestawie ćwiczeń dwukrotnie pojawił się problem istnienia (lub braku) otwieranego pliku.

W pierwszym przypadku chodziło o możliwość przypadkowego zniszczenia danych w trakcie tworze-

nia pliku o takiej samej nazwie jak plik wcześniej utworzony. W drugim przypadku występowała możli -

wość próby otwarcia do odczytu pliku, który nie istnieje. W obu przypadkach pomocna okaże się

funkcja Exists (Istnieje) zdefiniowana w klasie

File

(Plik) przestrzeni nazw System.IO (IO –

Input/Output – Wejście/Wyjście). Z funkcji tej należy korzystać w taki sam sposób jak np. z funkcji

klasy Math.

Przykład.

Dim boolPlikIstnieje as Boolean = System.IO.File.Exists("NazwaPliku.roz")

Funkcja zwraca wartość True jeśli istnieje plik o nazwie podanej jako parametr, lub False jeśli

plik nie istnieje. Przy tym nazwę pliku można poprzedzić literą napędu, lub nazwami katalogów, albo i

jednym i drugim. Jeśli podana jest wyłącznie nazwa pliku, to funkcja sprawdza katalog aplikacji. Ko -

lejne ćwiczenie pokazuje sposób w jaki można wykorzystać funkcję Exists.

Ćwiczenie 119
Zmodyfikować procedurę Main w taki sposób, aby otwieranie plików było „bezpieczne” –
poprzedzane sprawdzeniem istnienia pliku, który ma zostać otwarty.

1. Dodaj na początku procedury Main pusty wiersz.

2. Zadeklaruj zmienną strNazwaPliku typu String o wartości początkowej "PrintTest.txt".

3. Zadeklaruj zmienną boolPlikIstnieje typu Boolean i przypisz jej wynik sprawdzenia, czy

istnieje plik o nazwie przechowywanej w zmiennej strNazwaPliku.

Przykład.

Dim boolPlikIstnieje as Boolean = System.IO.File.Exists(strNazwaPliku)

4. Utwórz konstrukcję warunkową, której instrukcje zostaną wykonane pod warunkiem, że

zmienna boolPlikIstnieje ma wartość True.

Przykład.

If boolPlikIstnieje Then

5. Przenieś do konstrukcji warunkowej wszystkie instrukcje odnoszące się do pliku "Print-

Test.txt".

6. Przypisz, po konstrukcji warunkowej, zmiennej strNazwaPliku wartość "WritTest.txt" (lite-

rę „e” pominięto celowo, aby uzyskać nazwę pliku, który nie istnieje).

7. Przypisz zmiennej boolPlikIstnieje wynik sprawdzenia czy istnieje plik o nazwie przecho-

wywanej w zmiennej strNazwaPliku.

background image

8. Utwórz konstrukcję warunkową, której instrukcje będą wykonane pod warunkiem, że

zmienna boolPlikIstnieje ma wartość True.

9. Przenieś do konstrukcji warunkowej wszystkie instrukcje odnoszące się do pliku "Write-

Test.txt".

10.Uruchom aplikację.

Przykład działania aplikacji przedstawia rysunek:

Widać, że instrukcje zawarte w drugiej konstrukcji warunkowej nie zostały wykonane, gdyż funk-

cja Exists zwróciła wartość False. Konstrukcję warunkową można rozbudować o część

Else

,

w której zaprogramowane będzie informowanie użytkownika, że plik o podanej nazwie nie istnieje.

Modyfikację tą pozostawia się ćwiczącym do samodzielnego wykonania.

Wykonane ćwiczenia pozwalają utworzyć plik, zapisać do niego informacje, a także odczytać je.

Często występuje potrzeba zachowania informacji wcześniejszych, a dopisania nowych. Przykładem

mogą tu być wszelkiego rodzaju „logi”, czyli pliki przechowujące informacje o pewnych wydarzeniach.

Do tego rodzaju pracy potrzebny jest oddzielny (inny niż do tworzenia i zapisu oraz inny niż

do odczytu) tryb otwierania pliku. Plik musi być otwarty w taki sposób, aby możliwy był zapis, ale

miejsce zapisu musi być ustawione w pozycji końcowej pliku. Procedura FileOpen wykonuje takie

zadanie jeśli trzeci parametr ma wartość OpenMode.Append.

Przykład.

FileOpen(NumerPliku, NazwaPliku, OpenMode.Append)

Jeśli nie istnieje plik o nazwie podanej w parametrze NazwaPliku, to zostanie utworzony, a na -

stępnie otwarty do zapisu, podobnie jak w trybie Output. W kolejnym ćwiczeniu wykorzystany zosta -

nie tryb dopisywania informacji do pliku.

Ćwiczenie 120
Wykorzystać możliwe tryby pracy z plikiem o dostępie sekwencyjnym, w tym dokonać
dołączenia nowych danych do pliku.

1. Utwórz projekt aplikacji konsolowej.

2. Zadeklaruj zmienną intLiczba typu Integer.

3. Utwórz pętlę Do z warunkiem While sprawdzanym na końcu pętli. Pętla powinna być wy-

konywana tak długo, jak długo zmienna intLiczba nie jest równa zeru.

Rysunek 52: Zabezpieczenie przed otwieraniem nieistniejącego pliku działa.

background image

4. Zaprogramuj w pętli:

pobranie wartości zmiennej intLiczba od użytkownika,

otwarcie pliku „Liczby.dat” w trybie dopisywania,

Przykład.

FileOpen(1, "Liczby.dat", OpenMode.Append)

wyprowadzenie wartości zmiennej intLiczba do pliku; użyj procedury Write,

zamknięcie pliku.

5. Uruchom aplikację kilka razy, każdorazowo podając po kilka liczb całkowitych.

6. Sprawdź zawartość pliku Liczby.dat.

Umiemy już utworzyć plik, zapisać do niego informacje, otworzyć plik istniejący i odczytać z nie -

go informacje, a także otworzyć plik i dopisać do niego informacje. Plik Liczby.dat może mieć, przy-

kładowo, taką zawartość:

1,3,5,7,9,0,1,3,5,0,25,36,14,69,58,47,0,

Biorąc pod uwagę to, że zero stanowi rodzaj separatora, można powiedzieć, że plik zawiera trzy

ciągi liczb całkowitych. Ciągi mają różną długość, a ich liczba nie jest ograniczona. Przy odczycie da-

nych z pliku łatwo sprawdzić, że ciąg zakończył się – świadczy o tym odczytana w kolejnym kroku

wartość zerowa. Pozostaje jednak pytanie, skąd program ma wiedzieć, że ciąg, który właśnie zakoń-

czył odczytywać, był ostatni. Jest to pytanie o tyle istotne, że kolejny odczyt, gdy w pliku nie ma już

danych zakończy się błędem. Język Visual Basic 2010 posiada funkcję rozwiązującą ten problem.

Jest to funkcja EOF o wyniku typu

Boolean

. Jedynym parametrem funkcji jest numer otwartego pliku.

Przykład.

Dim boolPlikWPozycjiKońcowej As Boolean = EOF(NumerPliku)

Jeśli otwarty plik o numerze NumerPliku znajduje się w pozycji końcowej (ang. End Of File),

to wartością funkcji jest True, w przypadku przeciwnym False. Kolejne ćwiczenie zapoznaje z wyko-

rzystaniem funkcji EOF.

Ćwiczenie 121
Zaprojektować aplikację obliczającą sumy ciągów zawartych w pliku Liczby.dat.

1. Utwórz projekt aplikacji konsolowej i zapisz go.

2. Skopiuj plik Liczby.dat utworzony w ćwiczeniu 120. do katalogu bin\Debug utworzonego

projektu.

3. Zaprogramuj otwarcie do odczytu pliku Liczby.dat.

4. Utwórz pętlę While z warunkiem sprawdzającym czy plik otwarty w poprzednim punkcie

nie jest w pozycji końcowej.

background image

Przykład.

While Not Eof(1)

5. Zadeklaruj w pętli While zmienną intSuma typu Integer o wartości początkowej równej 0

oraz zmienną intLiczba typu Integer.

6. Utwórz pętlę Do z warunkiem While sprawdzanym na końcu pętli. Pętla powinna być wy-

konywana tak długo, jak długo wartość zmiennej intLiczba nie jest równa 0.

7. Zaprogramuj w pętli Do:

odczyt z pliku kolejnej liczby i przypisanie jej do zmiennej intLiczba; użyj procedury In-

put,

zwiększenie wartości zmiennej intSuma o wartość zmiennej intLiczba.

8. Zaprogramuj po zakończeniu pętli Do wyświetlenie w konsoli komunikatu o sumie ciągu.

9. Sprawdź działanie aplikacji.

Efekt działania aplikacji może być podobny do przedstawionego na rysunku:

Treść pliku tekstowego można odczytać w większości aplikacji pozwalających otworzyć i wy-

świetlić zawartość pliku. W związku z tym znaczenie plików tekstowych będzie się utrzymywać,

ze względu na to, że informacje w nich zawarte mogą być odczytane przez człowieka bez potrzeby

ich przetwarzania. Można nawet zaobserwować rosnące znaczenie plików tekstowych zawierających

znaczniki.

Jednak przetwarzanie sekwencyjne niesie ze sobą problemy sygnalizowane już wcześniej.

Przykładowo, nie istnieje taki tryb pracy z plikiem o dostępie sekwencyjnym, który pozwoliłby odczy -

tać wartość inną niż ta, która jest następna do odczytu. Nie można, po odczytaniu kilku wartości, „cof-

nąć się” do wartości już odczytanej – konieczne będzie zamknięcie pliku i ponowne odczytanie

wszystkich wartości poprzedzających pożądaną. Problemy takie nie występują w plikach o dostępie

swobodnym.

IX.2.

Pliki o dostępie swobodnym

Pliki o dostępie swobodnym (ang. Random Access Files) pozwalają na dostęp do informacji za-

wartej w dowolnym miejscu pliku. Nie ma potrzeby zmiany trybu dostępu, gdyż po otwarciu pliku

możliwy jest tak odczyt danych, jak i zapis danych. Jednak występuje ograniczenie innego typu, infor-

Rysunek 53: Projekt_121 w działaniu.

background image

macje zapisywane lub odczytywane muszą mieć ściśle określony rozmiar. Aby uwypuklić zalety try-

bów sekwencyjnego i swobodnego oraz różnice pomiędzy nimi pierwsze ćwiczenie niniejszego punk-

tu dotyczyć będzie pliku o dostępie sekwencyjnym.

Ćwiczenie 122
Zaprojektować aplikację pozwalającą utworzyć plik do przetwarzania w trybie
sekwencyjnym. Plik powinien przechowywać dane osobowe: Imię, Nazwisko i wiek w
latach.

1. Utwórz projekt aplikacji konsolowej.

2. Dodaj do projektu nowy moduł o nazwie Osoba.

3. Zadeklaruj w dodanym module strukturę DaneOsobowe o polach Imię i Nazwisko typu

String oraz Wiek typu Integer.

4. Zadeklaruj w procedurze Main (Module1) zmienną doOsoba typu DaneOsobowe.

5. Zaprogramuj otwarcie pliku Osoby.dat w trybie do zapisu.

6. Utwórz pętlę Do z warunkiem While sprawdzanym na końcu; pętla powinna pracować w

nieskończoność – zostanie zakończona instrukcją Exit Do.

7. Zaprogramuj w pętli:

pobranie od użytkownika imienia i przypisanie go polu Imię zmiennej doOsoba,

sprawdzenie wartości pola doOsoba.Imię i jeśli:

jest pustym łańcuchem znaków, pętla powinna się zakończyć – Exit Do,

nie jest pustym łańcuchem znaków, pobranie nazwiska i wieku osoby i przypisanie ich

odpowiednim polom zmiennej doOsoba, wartości pól powinny następnie zostać zapi-

sane do pliku; użyj procedury WriteLine.

8. Zaprogramuj po zakończeniu pętli zamknięcie pliku i otwarcie go w trybie do odczytu.

9. Utwórz pętlę While z warunkiem sprawdzającym czy otwarty plik nie jest w pozycji końco-

wej.

10.Zaprogramuj w pętli While:

odczyt kolejnych wartości z pliku i przypisanie ich odpowiednim polom zmiennej do-

Osoba,

wyświetlenie wartości pól zmiennej doOsoba w konsoli.

11. Zaprogramuj po zakończeniu pętli While zamknięcie pliku.

12.Uruchom aplikację i wprowadź dane kilku osób.

background image

Przykładowy efekt pracy aplikacji przedstawia rysunek:

W ćwiczeniu celowo użyto typu strukturalnego, aby zwrócić uwagę na uciążliwość wyprowadza-

nia wartości pól do pliku oraz ich odczytu z pliku. Wprawdzie konstrukcja

With

poprawia znacznie

sytuację, to jednak chciałoby się wyprowadzić do pliku wartość zmiennej doOsoba „za jednym zama-

chem”, a nie „na raty”.

Problem edycji pliku tekstowego byłby jeszcze bardziej skomplikowany. Konieczne byłoby wczy-

tanie wszystkich danych, edycja tych, które tego wymagają, utworzenie pliku i wyprowadzenie zmo-

dyfikowanych wartości. Pliki o dostępie swobodnym ułatwiają wykonanie takich zadań. Zaprojektowa-

nie aplikacji wykonującej identyczne zadanie, jak ta z ćwiczenia 122., na bazie plików o dostępie

swobodnym poprzedzimy ćwiczeniami wprowadzającymi do działań w tym trybie.

Najważniejszym wymaganiem przy pracy z plikami o dostępie swobodnym jest określona wiel-

kość porcji zapisywanych informacji. Oznacza, to, że zmienna, której wartość zapisujemy nie może

mieć dowolnego rozmiaru. Przyjrzyjmy się ostatnim dwóm wierszom przedstawionego wyżej przykła-

du występującym przed tekstem „Press any key to continue”. Widać, że liczba znaków występująca

w pierwszym z nich jest większa niż w drugim. Oznacza to, że zmienna doOsoba zajmowała więcej

bajtów gdy jej wartością była osoba o dłuższym imieniu. Dyskwalifikuje to zmienną doOsoba z wyko-

rzystania jej do pracy z plikami o dostępie swobodnym. Konieczne jest takie przygotowanie zmiennej,

aby jej wielkość była stała (podkreślmy wielkość, a nie zawartość). Wprowadzimy ograniczenie

na długość imienia i nazwiska (liczby typu Integer – Wiek – zawsze mają taki sam rozmiar). Do usta -

lenia („zafiksowania”) długości zmiennej typu

String

służy atrybut VBFixedString.

Przykład.

<VBFixedString(15)> Dim Imię As String

Zmienna Imię przechowywać będzie maksymalnie 15 znaków Jeśli liczba znaków w przypisy-

wanym łańcuchu przekracza ograniczenie, to tylko pierwsze 15 znaków znajdzie się w zmiennej.

Do otwierania plików o dostępie swobodnym stosuje się procedurę FileOpen, podając tryb

otwarcia OpenMode.Random. Pamiętamy, że procedura FileOpen posiada trzy opcjonalne parame-

try. Przy otwieraniu plików o dostępie swobodnym istotny jest ostatni, który przekazuje procedurze in -

formację o wielkości zapisywanych informacji. Parametr ten jest typu

Integer

, a jego wartość domyśl-

na to -1. Do określenia wielkości zapisywanej informacji można wykorzystać funkcję Len. Pamięta-

Rysunek 54: Projekt_122 w działaniu.

background image

my, że funkcja zdefiniowana jest w module Strings i pierwotnie używaliśmy jej do określania długości

łańcucha tekstowego. Funkcja posiada dwanaście przeciążonych wersji, które dla zmiennych róż-

nych typów zwracają liczbę bajtów zajmowanych przez zmienną danego typu.

Podsumowując, aby skorzystać ze swobodnego dostępu do plików musimy:

utworzyć zmienne o stałej wielkości; jeśli w skład zmiennej wchodzi pole typu String, to należy

zafiksować jego długość wykorzystując atrybut VBFixedString,

znać stałą wielkość zmiennej; można ją obliczyć wykorzystując jedną z wersji funkcji Len,

otworzyć plik podając w procedurze FileOpen tryb OpenMode.Random i jako ostatni parametr

stałą wielkość porcji zapisywanej informacji.

Wymagania te zostaną spełnione w kolejnym ćwiczeniu.

Ćwiczenie 123
Zaprojektować aplikację pozwalającą utworzyć plik o dostępie swobodnym
przechowujący dane osobowe.

1. Utwórz projekt aplikacji konsolowej.

2. Dodaj do projektu nowy moduł o nazwie Osoba.

3. Zdefiniuj strukturę DaneOsoboweStałyRozmiar o polach Imię i Nazwisko typu String po-

zwalających na przechowywanie do 15 znaków oraz Wiek typu Integer.

Przykład.

Structure DaneOsoboweSatłyRozmiar

<VBFixedString(15)> Dim Imię, Nazwisko As String
Dim Wiek As Integer

End Structure

4. Zadeklaruj w procedurze Main (Module1) zmienną dosrOsoba typu DaneOsoboweStały-

Rozmiar.

5. Zadeklaruj zmienną intWielkośćZapisu typu Integer i przypisz jej obliczoną przez funkcję

Len wielkość zmiennej dosrOsoba.

Przykład.

Dim intWielkośćZapisu As Integer = Len(dosrOsoba)

6. Zaprogramuj otwarcie pliku Osoby.rnd w trybie dostępu swobodnego, jako ostatni para-

metr użyj zmienną intWielkośćZapisu.

Przykład. Warto przypomnieć, że miejsca pominiętych parametrów opcjonalnych (czwartego i

piątego, w tym przypadku) wskazuje się przecinkami.

FileOpen(1, "Osoby.rnd", OpenMode.Random, , , intWielkośćZapisu)

7. Zaprogramuj zamknięcie pliku.

8. Uruchom aplikację dwukrotnie, każdorazowo sprawdź datę i godzinę utworzenia pliku.

background image

Funkcja FileOpen tworzy plik, jeśli ten nie istnieje, w przeciwnym przypadku otwiera istniejący.

Po otwarciu pliku w trybie swobodnym istnieje możliwość przesyłania danych w obu kierunkach –

do pliku i z pliku – bez konieczności przełączania trybu. W pliku można przesuwać punkt zapisu (od-

czytu) w dowolne miejsce.

Po utworzeniu pliku pozycja zapisu (odczytu) to pozycja początkowa i posiada ona numer 1. Je -

śli nastąpi zapis do pliku porcji danych, to pozycja zapisu przesunie się. Ta nowa pozycja ma numer

2. Każda kolejna pozycja ma numer większy niż poprzednia. Numery pozycji pozwalają identyfikować

konkretne miejsca w pliku i przemieszczać się do nich. Jest to możliwe wyłącznie dlatego, że wiel-

kość zapisywanych porcji informacji jest stała.

Do zapisywania danych do plików o dostępie swobodnym służy procedura FilePut. Posiada

ona 14 przeciążonych wersji. Podstawowa postać wywołania procedury wygląda następująco:

FilePut(NumerPliku, ZmiennaDoZapisania)

W optymalnym przypadku, gdy zmienna ma taką wielkość, jak ta podana w procedurze

FileOpen (szósty parametr), obszar pliku wykorzystany jest całkowicie przez dane. Jeśli wielkość

zmiennej jest mniejsza, to wolny obszar pozostający po końcu zapisu, nie zostanie wykorzystany

do przechowywania danych. Oznacza to stratę przestrzeni w systemie plików. W przypadku, gdy

zmienna ma wielkość większą niż ustalona podczas otwierania pliku, wystąpi błąd.

Procedura FilePut posiada opcjonalny parametr typu

Integer

o wartości domyślnej -1. Para-

metr ten pozwala wskazać pozycję w pliku, na której ma zostać zapisana wartość zmiennej. Jeśli pa -

rametr jest pominięty, to zapis następuje w aktualnej pozycji (tej, którą punkt zapisu osiągnął po po -

przednim zapisie/odczycie, lub przemieszczeniu). Ważne jest to, że dane zapisane na pozycji poda-

nej w procedurze FilePut zostaną zastąpione przez informacje zapisane w zmiennej.

Podobnym ograniczeniom podlega odczyt realizowany przy użyciu procedury FileGet, która

posiada 13 przeciążonych wersji, a jej podstawowa postać jest następująca:

FileGet(NumerPliku, ZmiennaDoOdczytania)

Procedura może przyjąć trzeci parametr, który wskaże pozycję w pliku, z której dane należy od-

czytać. Pokazuje to, że dostęp do danych w plikach o dostępie swobodnym uzasadnia nazwę tego

trybu pracy z plikami – tak zapis, jak i odczyt mogą być realizowane w dowolnym miejscu pliku.

Dodatkowo, możliwe jest uzyskanie informacji o numerze aktualnej pozycji zapisu/odczytu,

a także przesunięcie tej pozycji. Do obliczenia numeru aktualnej pozycji służy funkcja Seek, której je-

dynym parametrem jest numer pliku. Do przemieszczenia pozycji w pliku służy dwuparametrowa pro-

cedura Seek. Jej pierwszym parametrem jest numer pliku, drugim – numer pozycji, którą ma zająć

w pliku miejsce zapisu/odczytu.

W kolejnym ćwiczeniu zrealizujemy zapis do pliku o dostępie swobodnym, wykorzystując jedno-

cześnie funkcję Seek do śledzenia położenia pozycji zapisu w pliku oraz procedurę Seek do prze-

mieszczania tej pozycji.

background image

Ćwiczenie 124
Zaprogramować zapis do pliku danych przechowywanych w zmiennej strukturalnej.

1. Dodaj pusty wiersz pomiędzy instrukcjami FileOpen i FileClose.

2. Utwórz pętlę While wykonywaną w nieskończoność (zakończenie nastąpi w wyniku wy-

konania instrukcji Exit While) i zaprogramuj w niej:

wyświetlenie w konsoli numeru aktualnej pozycji zapisu w pliku,

Przykład.

Console.Writeline("Pozycja zapisu w pliku ma numer {0}", Seek(1))

pobranie od użytkownika imienia i przypisanie go polu Imię zmiennej dosrOsoba,

zakończenie pętli While, jeśli w polu Imię znajduje się pusty łańcuch, a w przeciwnym

przypadku:

pobranie nazwiska i wieku oraz przypisanie ich polom zmiennej dosrOsoba,

zapis do pliku wartości zmiennej dosrOsoba.

Przykład.

FilePut(1, dosrOsoba)

3. Zaprogramuj po zakończeniu pętli While:

przesunięcie pozycji zapisu/odczytu do miejsca o numerze 1,

Przykład.

Seek(1, 1)

przypisanie polom Imię i Nazwisko zmiennej dosrOsoba tekstu „Zmieniony”,

zapis do pliku wartości zmiennej dosrOsoba.

4. Uruchom aplikację, wprowadź kilka zestawów danych.

Dane zostały zapisane w pliku. Kolejne ćwiczenie polegać będzie na ich odczycie. Ponieważ

wśród 13. przeciążonych wersji procedury FileGet nie istnieje (z oczywistych powodów) taka, która

pozwala na odczyt z pliku danych typu

DaneOsoboweStałyRozmiar

, na korzyść projektu wykonywa-

nego w kolejnym ćwiczeniu nastąpi wyłączenie opcji Strict. Pozwoli to na wykorzystanie 13. wersji

procedury, która służy do pobierania wartości typu ValueType.

Ćwiczenie 125
Zaprogramować odczyt danych z pliku o dostępie swobodnym.

1. Wyłącz w pliku modułu opcję Strict, w tym celu:

dodaj przed wierszem rozpoczynającym blok modułu (wiersz ze słowem Module i na-

zwą modułu) pusty wiersz,

background image

wpisz instrukcję Option Strict Off.

2. Dodaj pusty wiersz przed instrukcją zamykającą plik (FileClose).

3. Zaprogramuj przemieszczenie pozycji zapisu/odczytu do miejsca o numerze 1 (początek

pliku).

4. Utwórz pętlę While wykonywaną tak długo, jak długo plik nie jest w pozycji końcowej i za -

programuj w niej:

wyświetlenie numeru aktualnej pozycji zapisu/odczytu,

odczyt do zmiennej dosrOsoba danych z pliku,

wyświetlenie wartości pól zmiennej dosrOsoba w konsoli.

5. Uruchom aplikację.

Przykładowy efekt działania aplikacji przedstawia rysunek:

Wprowadzanie danych do pliku zakończyło się po drugim zestawie danych. Pozycja zapisu zo-

stała ustawiona na miejsce o numerze 1, a polom Imię i Nazwisko zmiennej dosrOsoba został przypi-

sany tekst „Zmieniony”. Wartość zmiennej została zapisana do pliku na pierwszej pozycji. Po tym za -

pisie plik znalazł się w pozycji 2. Pozycja została następnie przesunięta na początek pliku i nastąpił

odczyt danych. Jako zadanie do samodzielnego rozwiązania pozostawia się ćwiczącym odpowiedź

na pytanie „Dlaczego Zmieniony Zmieniony ma 12 lat skoro Stefan Żeromski miał lat 19?”.

Przetwarzanie plików często jest długotrwałe i wiele współczesnych aplikacji wyświetla tzw. pa-

sek postępu – jego długość reprezentuje wykonaną część zadania. Przykładowo, jeśli w pliku znajdu-

je się 100 zapisów, a przetwarzany jest 19, to część wskaźnikowa zajmuje około 19% długości pa-

ska. W aplikacjach konsolowych częściej spotykanym rozwiązaniem jest wyświetlanie procentowego

wykonania zadania. Jednak chcąc wiedzieć jaki procent zapisów z pliku został już przetworzony ko -

nieczna jest wiedza na temat liczby zapisów w pliku. Liczbę tą można obliczyć dzieląc wielkość pliku

Rysunek 55: Projekt_123 w działaniu.

background image

przez wielkość porcji danych. Wiemy już jak obliczyć wielkość porcji danych. Do obliczania wielkości

pliku służą dwie funkcje, zwracające wynik typu

Long

, o istotnie różnym zastosowaniu:

FileLen – pozwala obliczyć wielkość w bajtach pliku, przechowywanego w systemie plików,

o nazwie podanej jako parametr funkcji. W nazwie można umieścić literę napędu, a także na -

zwy katalogów. Należy pamiętać o tym, że funkcja zwraca wielkość pliku odczytaną z danych

zawartych w systemie plików. Oznacza to, że jeżeli plik, którego wielkość odczytujemy, jest

otwarty, to obliczona wielkość pliku nie odzwierciedla zmian wprowadzonych w pliku od mo-

mentu otwarcia. Innymi słowy, funkcja zwraca wielkość pliku zapisaną w chwili ostatnio wyko-

nanego zamknięcia pliku.

LOF – pozwala obliczyć wielkość w bajtach pliku, otwartego przez procedurę FileOpen. Jedy-

nym parametrem funkcji jest numer otwartego pliku. Funkcja zwraca aktualną wielkość pliku.

Z powyższego wyszczególnienia wynika, że wartości zwracane przez obie funkcje mogą się

różnić. Zostanie to zaprezentowane w kolejnym ćwiczeniu.

Ćwiczenie 126
Zapoznać się z możliwością obliczania wielkości pliku przed jego otwarciem, oraz w
czasie gdy pozostaje otwarty.

1. Utwórz projekt aplikacji konsolowej.

2. Zdefiniuj w części deklaracyjnej modułu:

stałe:

BajtówNaInteger typu Integer o wartości 4, liczby typu Integer przechowywane są

w obszarze o wielkości 4 bajtów,

NazwaPliku typu String o wartości „Dane.int”,

Format typu String o wartości „Plik {0} ma wielkość {1} bajtów, zawiera {2} liczb

całkowitych.”, format ten będzie użyty przy wyprowadzaniu wyników obliczeń na

konsolę,

Przykład.

Const Format As String = "Plik {0} ma wielkość {1} bajtów, zawiera {2} liczb całkowitych."

CzteryBackSpace typu String o wartości: vbBack & vbBack & vbBack & vbBack,

stała ta posłuży do usuwania w konsoli czterech znaków wyprowadzonych jako

ostatnie;

Przykład.

Const CzteryBackSpace As String = vbBack & vbBack & vbBack & vbBack

procedurę Wypisz o dwóch parametrach przekazywanych przez wartość:

Plik typu String,

background image

Wielkość typu Long,

działanie procedury powinno polegać na wypisaniu w konsoli informacji przekazanych przez parame-

try.

Przykład.

Console.WriteLine(Format, Plik, Wielkość, Wielkość \ BajtówNaInteger)

bezparametrową procedurę Otwórz, w której zaprogramuj:

otwarcie pliku o nazwie przechowywanej w zmiennej NazwaPliku w trybie dostępu

swobodnego, ustalając wielkość porcji zapisu (odczytu) na wartość przechowywa-

ną w stałej BajtówNaInteger,

wyświetlenie w konsoli informacji o tym, że plik został otwarty;

bezparametrową procedurę Zamknij, w której zaprogramuj:

zamknięcie pliku,

wyświetlenie w konsoli informacji o tym, że plik został zamknięty.

3. Zadeklaruj w procedurze Main (Module1):

zmienne:

longWielkośćPliku typu Long, posłuży do przechowywania wyniku obliczenia wiel-

kości pliku,

intLiczba typu Integer, posłuży do przechowywania liczby całkowitej odczytanej

z pliku.

4. Zaprogramuj:

otwarcie pliku, użyj procedury Otwórz,

pętlę For, której zmienna sterująca zmienia się od 1 do 10000, a w niej zaprogramuj:

wyprowadzenie do pliku (FilePut) wartości losowej z przedziału 500000

÷

1000000,

konstrukcję warunkową, której instrukcje wykonywane są tylko wtedy, gdy wartość

zmiennej sterującej pętlą For jest wielokrotnością liczby 5000 (użyj operatora

Mod), a w niej zaprogramuj:

obliczenie wielkości otwartego pliku i przypisanie wyniku zmiennej longWielko-

śćPliku,

Przykład.

longWielkośćPliku = LOF(1)

użycie procedury Wypisz do wyświetlenia informacji o wielkości pliku i liczbie

danych w pliku;

background image

Przykład.

Wypisz(NazwaPliku, longWielkośćPliku)

zamknięcie pliku, po zakończeniu pętli For, użyj procedury Zamknij,

obliczenie wielkości zamkniętego pliku o nazwie przechowywanej w zmiennej Nazwa-

Pliku i przypisanie wyniku zmiennej longWielkośćPliku,

Przykład.

longWielkośćPliku = FileLen(NazwaPliku)

użycie procedury Wypisz do wyświetlenia informacji o wielkości pliku i liczbie danych

w pliku,

otwarcie pliku,

wyświetlenie w konsoli informacji o tym, że plik jest przetwarzany, użyj instrukcji Wri-

teLine konsoli,

pętlę While, wykonywaną tak długo, jak długo otwarty plik nie znajdzie się w pozycji

końcowej, a w niej zaprogramuj:

odczyt z pliku liczby całkowitej (FileGet) z przypisaniem jej wartości zmiennej in-

tLiczba,

pętlę For wykonywaną tyle razy ile wynosi wartość zmiennej intLiczba; pętla nie

zawiera instrukcji;

usunięcie z wiersza konsoli

9

czterech znaków, po zakończeniu pętli For; użyj in-

strukcji Write konsoli oraz stałej CzteryBackSpace,

Przykład.

Console.Write(CzteryBackSpace)

wyświetlenie w konsoli stopnia przetworzenia pliku w procentach,

Przykład.

Console.Write("{0}%", Seek(1) * 100 * BajtówNaInteger \ longWielkośćPliku)

zamknięcie pliku po zakończeniu pętli While; użyj procedury Zamknij.

5. Sprawdź działanie aplikacji.

9 Konsola posiada metody do przemieszczania kursora tekstowego (CursorLeft, CursorTop, SetCursorPosition). Użyto

stałej vbBack, aby wskazać możliwość użycia w konsoli znaków sterujących wydrukiem.

background image

Przykładowy efekt działania aplikacji (uchwycono moment podczas przetwarzania pliku) może

być następujący:

Warto, jako samodzielne ćwiczenie, sprawdzić różnicę pomiędzy wielkością pliku o dostępie se-

kwencyjnym przechowującego 1000 liczb typu Integer a wielkością pliku Dane.int. Można też spróbo -

wać odpowiedzieć na pytanie, jaki warunek muszą spełniać liczby, aby plik Dane.int miał większy roz-

miar niż plik sekwencyjny.

Tryb swobodny posiada wiele zalet, jednak w przypadku gdy zapisywana struktura posiada pola

typu łańcuchowego mogą wystąpić dwa problemy. Po pierwsze, zafiksowany łańcuch tekstowy może

być zbyt krótki do przechowania informacji wprowadzanej przez użytkownika. W takim przypadku tra -

cimy część danych. Po drugie, jeśli długość zafiksowanego łańcucha przewiduje najdłuższy możliwy

tekst, to wszystkie teksty krótsze będą powodem nieoptymalnego wykorzystania przestrzeni zbioru

danych. W wielu przypadkach rozwiązaniem tych problemów będzie tryb binarny dostępu do plików.

IX.3.

Binarny tryb dostępu do plików

W omawianym trybie nie robi się żadnych założeń co do wielkości zapisywanej informacji.

Do otwierania plików służy procedura FileOpen. Jako tryb otwierania podaje się wartość OpenMo-

de.Binary i nie wyszczególnia się wielkości porcji zapisu/odczytu, jak to miało miejsce w trybie swo -

bodnym.

Przykład.

FileOpen(NumerPliku, NazwaPliku, OpenMode.Binary)

Do zapisu i odczytu służą procedury FilePut oraz FileGet. Liczba zapisanych bajtów równa

jest wielkości zmiennej użytej w procedurze FilePut, a liczba odczytanych bajtów równa jest wiel-

kości zmiennej użytej w procedurze FileGet.

Pliki otwarte w trybie binarnym można odczytywać bajt po bajcie, albo porcjami o innej, dowol-

nej wielkości.

W poprzednich ćwiczeniach zasadniczo występował jeden otwarty plik. Język Visual Basic 2010

pozwala na jednoczesne przetwarzanie 255 plików. Może się okazać, że wyznaczenie numeru

dla otwieranego pliku nastręcza pewnych trudności. Ułatwieniem może być funkcja FreeFile o wy-

niku typu

Integer

. Funkcja zwraca numer, który nie jest używany przez inne otwarte pliki. Jeśli wyko-

rzystane są wszystkie możliwe numery, to podczas wykonywania funkcji wystąpi błąd. W kolejnym

Rysunek 56: Projekt_126 w działaniu.

background image

ćwiczeniu wykorzystana zostanie funkcja FreeFile do automatycznego przydziału numeru dla pli-

ków otwieranych w trybie binarnym; ćwiczenie ilustruje kopiowanie pliku.

Ćwiczenie 127
Wykorzystać tryb binarny do skopiowania pliku.

1. Utwórz projekt aplikacji konsolowej i zapisz go.

2. Skopiuj do katalogu bin\Debug utworzonego projektu plik Dane.int utworzony przez apli-

kację z ćwiczenia 126.

3. Zadeklaruj w procedurze Main zmienne intNumerPlikuKopiowanego, intNumerPlikuKopii

typu Integer oraz bytBajtDanych typu Byte. Pierwsze dwie zmienne posłużą do przecho-

wywania numerów przydzielonych plikom, trzecia będzie stanowić bufor, przez który

dane będą przenoszone z pliku kopiowanego do pliku kopii.

4. Zaprogramuj:

wyznaczenie wolnego numeru dla otwieranego pliku i przypisanie go zmiennej intNu-

merPlikuKopiowanego,

Przykład.

intNumerPlikuKopiowanego = FreeFile()

otwarcie pliku Dane.int w trybie binarnym,

Przykład.

FileOpen(intNumerPlikuKopiowanego, "Dane.int", OpenMode.Binary)

wyznaczenie wolnego numeru dla otwieranego pliku i przypisanie go zmiennej intNu-

merPlikuKopii,

otwarcie pliku Kopia.int w trybie binarnym,

pętlę While wykonywaną tak długo, jak długo plik kopiowany nie osiągnął pozycji koń-

cowej, a w niej zaprogramuj:

pobranie z pliku kopiowanego jednego bajta i przypisanie go zmiennej bytBajtDa-

nych,

Przykład.

FileGet(intNumerPlikuKopiowanego, bytBajtDanych)

zapisanie wartości zmiennej bytBajtDanych do pliku kopii.

zamknięcie, po zakończeniu pętli While, obu plików, wykorzystaj procedurę CloseFile

nie podając parametrów.

background image

5. Uruchom aplikację, a po jej ukończeniu porównaj wielkości plików Dane.int i Kopia.int

(ciekawe informacje zawierają okna Właściwości – warto porównać wielkość Rozmiar

oraz Rozmiar na dysku

10

).

IX.4.

Procedury i funkcje związane z przetwarzaniem plików

W module FileSystem zdefiniowano, oprócz opisanych wcześniej procedur i funkcji, wiele me-

tod przydatnych podczas przetwarzania plików. W ćwiczeniu 119. do sprawdzenia czy istnieje plik

o określonej nazwie użyto funkcji Exists klasy File. Moduł FileSystem posiada funkcję Dir, która

może być wykorzystana w tym samym celu. Funkcja posiada dwie wersje: bezparametrową oraz

dwuparametrową. Wynik funkcji jest typu

String

.

Wersja dwuparametrowa przyjmuje jako pierwszy parametr łańcuch tekstowy, który może

przedstawiać dozwoloną ścieżkę dostępu do pliku (katalogu) i może zawierać znaki wieloznaczne „*”

oraz „?”. Drugi parametr przyjmuje jako wartość jedną z wartości enumeracji FileAttribute: Nor-

mal – 0, ReadOnly – 1, Hidden – 2, System – 4, Volume – 8, Directory – 16, Archive – 32. Wynik

funkcji Dir jest typu

String

i przedstawia pierwszy element systemu plików pasujący do wzorca prze-

kazanego jako pierwszy parametr i posiadający atrybuty przekazane przez drugi parametr.

Przykład. Zakłada się że strElement jest typu String.

strElement = Dir("*.*", FileAttribute.Normal)

Po wywołaniu, jak w przykładzie powyżej, zmienna strElement zawiera nazwę pliku o atrybucie

Normal, który znajduje się w katalogu aplikacji. Jeśli w katalogu nie ma żadnego pliku, to zmienna za-

wiera pusty ciąg znaków. Takie działanie funkcji Dir pozwala przeglądać iteracyjnie, lub rekurencyj-

nie dowolny katalog.

Bezparametrowa postać funkcji Dir może zostać zastosowana po wcześniejszym użyciu funk-

cji Dir z parametrami, wtedy wyszukuje takie elementy systemu plików, jakby posiadała parametry

wcześniej ustalone.

Przykład.

strElement = Dir("*.sys", FileAttribute.Hidden)
While strElement <> ""

Console.WriteLine(strElement)
strElement = Dir()

End While

Ponieważ w pierwszym wywołaniu funkcji Dir ustalono, że poszukiwane są pliki ukryte o na-

zwie z rozszerzeniem .sys, to kolejne (bezparametrowe) wywołania będą dotyczyły tylko takich pli-

ków, które pasują do ustalonych wcześniej parametrów. Kolejne ćwiczenie pokazuje przykład zasto-

sowania funkcji Dir.

10 Warto poszukać informacji o sposobie zapisu plików na dysku. Wiedza ta pozwala oszczędniej gospodarować prze-

strzenią dyskową.

background image

Ćwiczenie 128
Zaprojektować aplikację wyświetlającą wszystkie pliki o nazwie config w katalogu
głównym dysku C:.

1. Utwórz projekt aplikacji konsolowej.

2. Zadeklaruj w procedurze Main zmienną strPlik typu String i przypisz jej wynik funkcji Dir

podając jako pierwszy parametr łańcuch tekstowy pasujący do nazwy „config” plików

umieszczonych w katalogu głównym dysku C:.

Przykład.

Dim strPlik As String = Dir("C:\config.*")

3. Utwórz pętlę While wykonywaną tak długo, jak długo zmienna strPlik nie zawiera pustego

łańcucha znaków i zaprogramuj w niej:

wyświetlenie w konsoli wartości zmiennej strPlik,

pobranie nazwy następnego pasującego do wzorca pliku i przypisanie jej zmiennej

strPlik.

Przykład.

strPlik = Dir()

4. Uruchom aplikację.

Efekt działania programu może być podobny do przedstawionego na rysunku:

Prześledźmy kolejne etapy wykonania aplikacji. W chwili deklarowania zmiennej strPlik wykony-

wana jest funkcja Dir, która przeszukuje katalog C:\. Zostaje odnaleziony pierwszy plik o nazwie pa-

sującej do wzorca, czyli config.kopia128 i jego nazwa przypisana zostaje do zmiennej strPlik. Para-

metry wywołania funkcji Dir są ustalone. W pętli zostaje sprawdzony warunek i okazuje się, ze

zmienna strPlik nie zawiera pustego łańcucha znaków – pętla będzie wykonywana. W pierwszej in-

strukcji pętli wyświetlona zostaje w konsoli wartość zmiennej strPlik. Następnie funkcja Dir poszuku-

je kolejnego pasującego do zapamiętanego wzorca pliku i przypisuje jego nazwę do zmiennej strPlik.

Pętla wykonywana jest tak długo, aż (po odnalezieniu ostatniego pliku pasującego do wzorca) funk-

cja Dir zwróci pusty łańcuch znaków.

Przy omawianiu funkcji Dir pojawiło się pojęcie atrybutu. Pliki tworzone w ćwiczeniach dotyczą-

cych dostępu sekwencyjnego, swobodnego, binarnego automatycznie otrzymywały atrybut Archive.

Istnieje możliwość zmiany atrybutów istniejącego pliku oraz możliwość odczytania atrybutów takiego

Rysunek 57: Projekt_128 w działaniu.

background image

pliku. Do ustalania atrybutów pliku służy dwuparametrowa procedura SetAttr, której pierwszy para-

metr to łańcuch tekstowy określający plik, a drugi parametr określa atrybut pliku, który ma zostać

ustawiony (włączony). Drugi parametr przyjmuje jako wartość jedną ze stałych enumeracji FileAttribu-

te.

Przykład.

SetAttr("Nazwa.roz", FileAttribute.Hidden)

Po wykonaniu takiego wywołania plik Nazwa.roz będzie plikiem ukrytym. Możliwe jest ustawie-

nie więcej niż jednego atrybutu. Aby włączyć np. atrybuty Hidden i ReadOnly należy jako drugi para-

metr podać sumę wartości tych atrybutów.

Przykład.

SetAttr("Nazwa.roz", FileAttribute.Hidden + FileAttribute.ReadOnly)

Należy przy tym zauważyć, że wartości stałych zdefiniowanych w enumeracji FileAttribute są

potęgami liczby 2. W związku z tym, biorąc pod uwagę binarną reprezentację sumy tych atrybutów

można powiedzieć, że każdy dodany atrybut ustawia odpowiedni bit sumy. Przykładowo postać dwój-

kowa sumy użytej w przykładzie jest następująca:

(FileAttribute.Hidden + FileAttribute.ReadOnly)

B

00000011

Do zagadnienia tego powrócimy za chwilę przy omówieniu odczytu atrybutów pliku. Do pobra-

nia atrybutów pliku istniejącego w systemie plików służy funkcja GetAttr. Jedynym parametrem tej

funkcji jest nazwa pliku, a wynik typu FileAttribute przedstawia zestaw ustawionych atrybutów pliku.

Przykład. Zakłada się, że faAtrybuty jest typu FileAttribute.

faAtrybuty = GetAttr(NazwaPliku)

Ponieważ funkcja zwraca wartość wynikającą ze wszystkich atrybutów pliku, potrzebny jest spo-

sób „wyłuskania” tych atrybutów. Załóżmy, że wartość binarna zmiennej faAtrybuty wynosi 00000011

(dziesiętne 3), to znaczy, że ustawione są atrybuty Hidden i ReadOnly pliku. Aby dowiedzieć się, czy

plik posiada atrybut ReadOnly posłużymy się wartością stałej ReadOnly (00000001). Iloczyn logiczny

(

And

) dwóch liczb daje w wyniku liczbę, w której ustawione są tylko te bity, które ustawione są w obu

liczbach wchodzących do iloczynu.

Przykład.

01010101

And 00000100

00000100

Widać, że jeśli oblicza się iloczyn dowolnej liczby i liczby, która posiada ustawiony tylko jeden

bit (nazywa się takie liczby maskami), w wyniku uzyskuje się albo zero, albo wartość maski. Stąd jeśli

iloczyn logiczny pewnej liczby i maski równy jest masce, to znaczy, że „maskowana” liczba posiada

ustawiony ten sam bit, który ustawiony jest w masce.

background image

Zbiór stałych enumeracji FileAttribute spełnia warunki stawiane przed maskami. Każda stała ma

ustawiony inny (i tylko jeden) bit. Pozwala to na użycie tych stałych jako masek. Kolejne ćwiczenie

ilustruje ustawianie i odczyt atrybutów plików.

Ćwiczenie 129
Zaprojektować aplikację, która utworzy plik, wyłączy wszystkie jego atrybuty, a
następnie ustawi kolejno atrybuty Archive i ReadOnly. Po ustawieniu atrybutów
aplikacja powinna odczytać i wyświetlić informację o atrybutach utworzonego pliku.

1. Utwórz projekt aplikacji konsolowej.

2. Wyłącz opcję Strict w pliku modułu, przy włączonej opcji Strict konieczne byłoby użycie

jawnej konwersji sumy atrybutów na typ FileAttribute, np.

faAtrybuty = CType(faAtrybuty + FileAttribute.Archive, FileAttribute)

Uwaga. Sposób wyłączenia opcji Strict dla modułu przedstawiony jest w ćwiczeniu 125.

3. Zadeklaruj w procedurze Main zmienną faAtrybuty typu FileAttribute o wartości początko-

wej Normal.

4. Zaprogramuj utworzenie pliku Atrybuty.txt (otwarcie i zamknięcie pliku o podanej nazwie

skutkuje jego utworzeniem).

5. Ustaw atrybut Normal dla pliku Atrybuty.txt.

Przykład.

SetAttr("Atrybuty.txt", faAtrybuty)

6. Dodaj do zmiennej faAtrybuty wartość stałej Archive.

7. Ustaw ponownie atrybuty dla pliku.

8. Dodaj do zmiennej faAtrybuty wartość stałej ReadOnly.

9. Ustaw ponownie atrybuty pliku.

10.Przypisz zmiennej faAtrybuty wartość stałej Normal – pozwoli to dowieść, że odczytane

atrybuty pliku rzeczywiście były ustawione.

11. Odczytaj atrybuty pliku i przypisz odczytaną wartość zmiennej faAtrybuty.

Przykład.

faAtrybuty = GetAttr("Atrybuty.txt")

12.Utwórz konstrukcję warunkową, której instrukcje wykonane będą tylko wtedy, gdy zmien-

na faAtrybuty posiada ustawiony ten sam bit co stała ReadOnly.

Przykład. (Nawiasy użyto w celu poprawienia czytelności zapisu.)

If (faAtrybuty And FileAttribute.ReadOnly) = FileAttribute.ReadOnly Then

13.Zaprogramuj w konstrukcji warunkowej wyświetlenie informacji o tym, że plik posiada

atrybut „tylko do odczytu”.

background image

14.Zaprogramuj drugą konstrukcję warunkową sprawdzającą czy plik posiada atrybut Archi-

ve i wyświetlającą informację o tym fakcie.

15.Uruchom aplikację.

Efekt działania aplikacji może być podobny do przedstawionego na rysunku:

Ostatnim elementem związanym z plikiem jest data i moment jego ostatniej modyfikacji. Do od-

czytu takich danych służy funkcja FileDateTime, której jedynym parametrem jest nazwa pliku, a

wynik (typu

DateTime

) zawiera szczegółowe dane. Kolejne ćwiczenie zapoznaje z działaniem funkcji

FileDateTime.

Ćwiczenie 130
Użyć funkcji FileDateTime w celu ustalenia daty ostatniej modyfikacji pliku.

1. Utwórz aplikację konsolową.

2. Zaprogramuj wyświetlenie w konsoli informacji o dacie ostatniej modyfikacji pliku Auto-

exec.bat.

Przykład.

Console.WriteLine("Plik Autoexec.bat został zmodyfikowany {0}.", _
FileDateTime("C:\Autoexec.bat").ToLongDateString)

3. Uruchom aplikację.

Efekt działania aplikacji może być podobny do przedstawionego na rysunku:

Rysunek 58: Projekt_129 w działaniu.

Rysunek 59: Projekt_130 w działaniu.


Document Outline


Wyszukiwarka

Podobne podstrony:
09 Zestaw ćwiczeń gimnastycznych, zabawy i ćwiczenia gimnastyczne
Specjalne ćwiczenia przygotowawcze stosowane przy nauce pływania kraul na grzbiecie
04 Petle programowe cwiczenia przygotowujace
02 Wprowadzenie do Visual Basic cwiczenia przygotowujace
08 Debugowanie cwiczenia przygotowujace
L.A. Konspekt - Ćwiczenia przygotowujące do nauczania trójskoku i startu niskiego, AWF, Lekkoatletyk
2008-09. WE.Cwiczenia z Makroekonomii.30+15. Dzienne, EKONOMIA, Rok 1, Podstawy makroekonomii
ćwiczenia przygotowujące do nauki czytania i pisania, Ćwiczenia usprawniające
Przyklady cwiczen przygotowujacych dzieci 6, Pedagogika
Cwiczenia przygotowujace do nauki pisania w szkole zycia
ćwiczenia 2 i 3 - przygotowane na zajęcia, studia pedagogiczne, Rok 4, Teoretyczne podstawy pracy op
plan zajęć administracja semestr letni 16.02.09-05.06.09, pliki zamawiane, edukacja
PAS 09 pliki zdefiniowane, semestr I, Programowanie Komputerowe
07 Algorytmy cwiczenia przygotowujace
Temat „Jesień – ćwiczenia przygotowujące do nauki pisania”

więcej podobnych podstron