Strumienie
Adam Boduch
Co to są te strumienie? Jak by to najprościej wyjaśnić? Otóż strumienie to ciąg danych, który może być zapisywany np. w pliku. Wyobraź sobie taką książkę adresową. Masz na formie listę adresów oraz imion zgrupowanych np. na komponencie typu ListView. Chcesz te adresy teraz zapisać tak jak to ma miejsce np. w Windowsowej książce adresowej. Na końcu tego artykułu będzie rozwiązanie tego problemu - zapisywanie wszystkiego do jednego pliku i odczytanie. A wszystko za pomocą strumieni.
Podstawową klasą dla strumieni jest klasa TStream. To od niej wywodzą się pozostałe obiekty będące samodzielnym typem. Oto one:
TFileStream - służy do operacji na plikach;
TMemoryStream - do operacji danych w pamięci komputera;
TResourceStream - operuje na zasobach plików;
TStringStream - służy do operacji na zmiennych tekstowych (String).
W tej chwili pewnie nie wiesz jak to wszystko zastosować itp. Ale nie martw się - zaraz wszystko stanie się jasne gdyż wykorzystanie strumieni nie jest niczym nadzwyczajnym.
Np. wykorzystanie typu TResourceStream. Oto przykład wyciągnięcia z naszego programu EXE bitmapy o nazwie 'MOJA', a następnie zapisanie tej bitmapy na dysku:
var
S : TResourceStream;
begin
S := TResourceStream.Create(hInstance, 'MOJA', RT_BITMAP);
S.SaveToFile('C:\\main.bmp');
S.Free;
Sam przyznasz, że to nie jest nic trudnego, prawda? Najpierw deklarowana jest zmienna typu "TResourceStream", a następnie jest ona tworzona. W konstruktorze zmiennej pierwszym parametrem jest uchwyt pliku, drugim nazwa zasobu, a ostatni parametr to typ zasobu. Typy zasobów możesz poznać w systemie pomocy Delphi pod zakładką "TResourceStream".
No i następnie wyciągnięty zasób zostaje zapisany na dysku.
Tak jak opisałem wyżej strumienie mogą także operować na plikach. Trzeba jednak podać wówczas tryb otwarcia pliku - np:
var
S : TFileStream;
begin
S := TFileStream.Create('C:\\plik.txt', fmOpenWrite);
Pierwszym parametrem tego konstruktora jest nazwa pliku, którego będzie dotyczyć operacja, a drugim parametrem jest właśnie tryb otwarcia. Ten parametr może mieć następującą wartość:
fmCreate Tworzy nowy plik jeżeli nie istnieje na dysku;
fmOpenRead Otwiera plik jedynie do odczytu;
fmOpenWrite Otwiera plik do zapisu;
fmOpenReadWrite Otwiera do zapisu lub do odczytu;
Świetnie - jeżeli masz już plik otwarty możesz przystąpić do operacji na tym właśnie pliku.
Podstawowymi funkcjami są polecenia zapisu i odczytu. Robią to funkcje zapisu i odczytu:
Write, WriteBuffer - zapisuje dane do pliku;
Read, ReadBuffer - odczyt;
Różnica pomiędzy dwoma poleceniami wykonywującymi tę samą czynność jest taka, że polecenia Read i Write to funkcje i zwracają liczbę danych wpisanych do pliku. Przykładowy zapis rekordu do pliku mógłby wyglądać tak:
var
S : TFileStream;
Rec : record
Name : String;
ID : Byte;
end;
begin
Rec.Name := 'Adam';
Rec.ID := 2;
S := TFileStream.Create('C:\\plik.txt', fmCreate);
S.WriteBuffer(Rec, SizeOf(Rec));
S.Free;
To spowoduje zapis danych do pliku. Możesz teraz np. dopisać do istniejących danych kolejny rekord - służy do tego polecenie Seek:
S := TFileStream.Create('C:\plik.txt', fmOpenWrite);
S.Seek(SizeOf(Rec), soFromEnd);
W tym wypadku polecenie Seek przesunie miejsce zapisu danych na sam koniec. Pierwszym parametrem jest wielkość danych - określone jest to poprzez SizeOf. Kolejny parametr to miejsce w którym ma się rozpocząć operacja zapisu. W tym wypadku będzie to na samym końcu pliku. Możesz w tym miejscu podać dowolną wartość lub:
soFromBeginning - na samym początku;
soFromCurrent - aktulne miejsce;
soFromEnd - sam koniec;
Do określenia ilości rekordów znajdujących się w pliku możesz zastosować coś takiego:
Rozmiar := S.Size div SizeOf(Rec);
Zmienna Rozmiar będzie zawierać ilość rekordów. Zasada jest prosta: właściwość Size określa ilość bajtów zapisanych w pliku - dzieląc to przez rozmiar ( w bajtach ) rekordu otrzymamy ilość rekordów znajdujących się w pliku.
Istnieje jeszcze polecenie Position, która określa aktualną pozycje w pliku.
To właściwie wszystko co najważniejsze.
Strumienie umożliwiają także zapisywanie do pliku ustawień komponentów - np. położenia komponentu na formie itp. Do tego służą polecenia: WriteComponent oraz ReadCompoennt.
Proszę bardzo - zapisanie komponentu o nazwie "btnMove" do pliku:
var
FileStream : TFileStream;
begin
if FileExists('setup.txt') then // jezeli istnieje plik
FileStream := TFileStream.Create('setup.txt', fmOpenWrite) else
FileStream := TFileStream.Create('setup.txt', fmCreate); //w przeciwnym wypadku stworz plik
FileStream.WriteComponent(btnMove); // zapisz ustawienia komponentu TButton
FileStream.Free; // zwolnij zmienna
W tym wypadku jeżeli plik nie istnieje to zostanie stworzony, a jeżeli istnieje - zostanie jedynie otwarty do zapisu.
Teraz odczyt wygląda bardzo podobnie:
procedure TMainForm.FormCreate(Sender: TObject);
var
FileStream : TFileStream;
begin
if not FileExists('setup.txt') then Exit; //jezeli plik nie istnieje - nie rob nic
FileStream := TFileStream.Create('setup.txt', fmOpenRead); //otworz tylko do odczytu
FileStream.ReadComponent(btnMove); // odczytaj ustawienia komponentu
FileStream.Free;
end;
Istnieje jeszcze jedna przydatna funkcja - CopyFrom. Przedstawia się ona następująco:
function CopyFrom ( Source: TStream; Count: Longint ) : Longint;
Służy ona do przypisania jednemu strumieniowi wartości drugiego strumienia.
Polecam ściągnięcie źródła programu Kartoteka, który wykorzystując strumienie zapisuje do pliku nazwę oraz e-mail. Jest to taka książka adresowa.
Lipa, mialo byc o strumieniach, a tu zapisywanie plikow :/ A o TMemoryStream i TStringStream zapomniałes?
Jest w Download Delphi
pod nazwą Dane (Poprawione)
tu link bezposredni
http://4programmers.net/download.php?id=275
pewnie w dziale Programy!!!
skad wziac ten kod do "Kartoteki" ???