Operacje na plikach z poziomu aplikacji
W tym artykule będą wyjaśnione operacje na plikach z poziomu aplikacji. Czym jest plik? Plik jest to zorganizowany zbiór danych przechowywany na dysku twardym, płytach CD/DVD, pendrive, itd. Operujemy na plikach dosyć często przy obsłudze/tworzeniu baz danych, jednakże zastosowań jest o wiele więcej(np. pliki konfiguracyjne, tymczasowe - przechowujące jakieś informacje na dany moment).
Czym jest atrybut danego pliku? Każdy plik ma swoją listę atrybutów(cech). Przykładem jest atrybut "Tylko do odczytu"(ang. Read-Only), gdy ten atrybut jest aktywny - większość aplikacji nie ma wpływu na dany plik(może go odczytać, ale rzadko kiedy modyfikować). Atrybuty dotyczące danego pliku są przechowywane w bajcie(jeden atrybut odpowiada jednemu bitowi, cała informacja o atrybutach pliku jest zapisywana na czterech bitach). Przykłady atrybutów w Delphi:
- Plik tylko do odczytu - faReadOnly
- Plik ukryty - faHidden
- Plik systemowy - faSysFile
Jest jeszcze jeden atrybut - faArchive - jest on powiązany z tworzeniem kopii zapasowych. Gdy tworzy się nowy plik, wszystkie atrybuty są wyłączone(prócz faArchive). Aby dokonać zmian na atrybutach pliku, użyjemy funkcji FileGetAttr oraz FileSetAttr. Teraz możesz zadać sobie pytanie? Po co mi te cechy pliku? Co by było np. gdybyś miał potrzebę zmodyfikować jakiś plik, który jest "Tylko do odczytu"?
Najłatwiejszym sposobem jest po prostu wyłączyć ten atrybut, zmienić to co chcemy i przywrócić atrybut spowrotem. Wracając do tego co wcześniej mówiłem - informacje o cechach są przechowywane w bajcie. Jak wszyscy wiemy(no może nie wszyscy), bajt = 8 bitów.
- Bit 0 - bit dla atrybutu "Tylko do odczytu"
- Bit 1 - bit dla atrybutu "Plik ukryty"
- Bit 2 - bit dla atrybutu "Plik systemowy"
- Bit 3 - bit dla atrybutu "Volume ID"
- Bit 4 - bit dla atrybutu "Podkatalogi"
- Bit 5 - bit dla atrybutu "Archive"(to co mówiłem wcześniej - kopie zapasowe - w każdym pliku jest włączony na starcie)
- Bit 6 & 7 - bity te są nie używane
Teraz przyjmijmy, że chcielibyśmy włączyć atrybut "Plik ukryty". Pierwsze co przychodzi na myśl to użycie funkcji której podałem wcześniej FileSetAttr i ustawić faHidden. faHidden - ma wartość 00000002 binarnie, oraz 02 heksadecymalnie. Jednakże ustawiając tryb ukryty - skasowalibyśmy atrybut odpowiadający za tworzenie kopii zapasowych(ustawiając jeden atrybut wyzerowalibyśmy pozostałe). System binarny i heksadecymalny(tzw. szesnastkowy) to systemy podobne do dziesiętnego(tego, którego używamy na co dzień). W systemie dziesiętnym mamy liczby od 0 do 9, natomiast w systemie binarnym 0 oraz 1. W systemie szesnastkowym posługujemy się liczbami od 0 do F, tj. 0...9, A, B, C, D, E, F. System szesnastkowy pozwala na łatwą zamianę liczby z systemu binarnego. Napisałem wcześniej, że bajt ma osiem bitów. Przykładową liczbą niech będzie 188, w systemie binarnym zapiszemy ją 10111100, w szesnastkowym jako BC. Jeśli chcielibyśmy zapisać w naszym kodzie liczbę w systemie szesnastkowym, poprzedzamy ją znakiem "$"(dolara), czyli $BC. Patrząc na wartość binarną naszego BC, tj. 10111100 - można zauważyć, które atrybuty są aktywne poprzez czytanie od prawej do lewej strony. Tak więc aktywny jest atrybut "Archive", "Podkatalogi", "Volume ID", "Plik systemowy", "Tylko do odczytu". Teraz gdybyśmy chcieli ustawić atrybut "Plik ukryty" użylibyśmy funkcji FileSetAttr, włączając atrybut "Plik ukryty", jednakże zerując pozostałe. Wprowadzamy nową wartość, a poprzednia jest kasowana. A więc, jeśli chcielibyśmy ustawić dwa atrybuty na raz, piszemy tak:
Kod:
FileSetAttr('plik.txt', faHidden+faArchive);
Wtedy włączony jest i faHidden & faArchive. Hm no dobrze, ale co jeśli mamy ochotę tak jak mówiłem wcześniej dołączyć/wyłączyć jakiś atrybut? Rozwiązanie:
Kod:
var
atrybut : Integer; // 1
begin
atrybut := FileGetAttr('plik.txt'); // 2
atrybut := atrybut OR faHidden; // 3
FileSetAttr('plik.txt', atrybut); // 4
end;
- Deklaracja zmiennej "atrybut" typu integer.
- Pobieranie cech pliku do wyżej zadeklarowanej zmiennej za pomocą FileGetAttr();
- Użycie operatora 'OR' w celu dopisania nowego atrybutu.
- Przypisanie plikowi nowego atrybutu za pomocą FileSetAttr();
Banalne, czyż nie? Skoro już trochę wiecie o cechach pliku, można by stworzyć jakiś program. Odpalamy Borland Delphi! Dodajemy komponenty:
- Button1 - ustawiamy Caption(opis) na "Zapisz"
- Button2 - ustawiamy Caption(opis) na "OK"
- Button3 - ustawiamy Caption(opis) na "Wyjdź"
- Edit - kasujemy wszystko co jest w Text
- FileListBox - FileEdit ustaw na Edit1
- DirectoryListBox - FileList ustaw na FileListBox1
- DriveComboBox - DirList ustaw na DirectoryListBox1
- CheckBox - opis "Tylko do odczytu"
- CheckBox - opis "Plik ukryty"
- CheckBox - opis "Plik systemowy"
- CheckBox - opis "Archive"
Układamy sobie to wszystko mniej więcej tak jak ja:

------------------------
Pod:
Kod:
"implementation
{$R *.dfm}"
Piszemy:
Kod:
var
nazwa : String;
atrybut : Integer;
------------------------
Obsługa kliknięcia przycisku "Zapisz":
Kod:
procedure TForm1.Button1Click(Sender: TObject); // PRZYCISK ZAPISZ
begin
atrybut := 0;
if CheckBox1.Checked = True then
atrybut := atrybut OR faReadOnly;
if CheckBox2.Checked = True then
atrybut := atrybut OR faHidden;
if CheckBox3.Checked = True then
atrybut := atrybut OR faSysFile;
if CheckBox4.Checked = True then
atrybut := atrybut OR faArchive;
FileSetAttr(nazwa, atrybut);
end;
Obsługa kliknięcia przycisku "OK":
Kod:
procedure TForm1.Button2Click(Sender: TObject);
begin
nazwa := Edit1.Text;
atrybut := FileGetAttr(nazwa);
if atrybut and faReadOnly = faReadOnly then
CheckBox1.Checked := True;
else
CheckBox1.Checked := False;
if atrybut and faHidden = faHidden then
CheckBox2.Checked := True;
else
CheckBox2.Checked := False;
if atrybut and faSysFile = faSysFile then
CheckBox3.Checked := True;
else
CheckBox3.Checked := False;
if atrybut and faArchive = faArchive then
CheckBox4.Checked := True;
else
CheckBox4.Checked := False;
end;
Obsługa kliknięcia przycisku "Wyjdź":
Kod:
procedure TForm1.Button3Click(Sender: TObject);
begin
Application.Terminate;
end;
Tym bym zakończył pierwszą część artykułu. Myślę, że kod jest zrozumiały. Kolejne części ukażą się za parę dni. Mam nadzieje, że to się komuś przyda.
Pozdrawiam.