Jason. Cała informatyka w jednym miejscu!

Trzecim bytem jaki zostanie przedstawiony podczas opowiadanek o obsłudze plików w "CSharpie" będzie "FileStream". "FileStream" w języku C# jest takim punktem startowym dla wykonywania podstawowych operacji. Dzięki wspomnianej klasie, możemy sobie wybrać w jaki sposób chcemy operować na pliku podając jeden z trybów dostępu. Ale szczegóły tego procederu opiszemy sobie już w środku.

"FILESTREAM" W JĘZYKU C# JESZCZE JEDNYM SPOSOBEM OBSŁUGIWANIA PLIKÓW

Był już opis "FileInfo" dla plików i "DirectoryInfo" dla katalogów. Wydawać by się mogło, że oto ukończyliśmy omawianie wszystkich podstawowych rzeczy przeznaczonych do obsługi plików. A tu niespodzianka :D! Jest jeszcze kilka odmian, które mogą się Wam przydać. Nie napiszę, że przydadzą się na pewno, bo uciekłbym się do kłamstwa ;). Muszę założyć, że kiedyś jednak ta wiedza stanie się przydatna, więc siłą rzeczy muszę o tym napisać.

"FileStream" w języku C# w odróżnieniu od poprzednich klas, nie jest częścią "FileSystemInfo" ponieważ charakteryzuje się inną metodyką obsługiwania plików. Tamte dwie poprzednie dotyczyły obsługi plików i katalogów "na zewnątrz". Tworzenie i usuwanie dotyczyło samego pliku. Wydobywanie informacji o nim dotyczyło samego pliku. "FileStream" zaś pozwala na edytowanie...zawartości pliku, czyli modyfikacje dotyczącą wnętrza pliku :O! Możecie się już domyślać jakie operacje zostaną zawarte w opisywanej klasie. Mianowicie dopisywanie do pliku, nadpisywanie pliku etc. Tego typu operacje, choć samo tworzenie i usuwanie także jest dostępne.

WŁAŚCIWOŚCI KLASY "FILESTREAM"

A teraz właściwości, kochani. Oto zbiór jakim dysponuje "FileStream" w języku C#:

NAZWA ZNACZENIE MODYFIKOWALNA
CanRead Ustalenie czy bieżący strumień obsługuje odczyt nie
CanSeek Ustalenie czy bieżący strumień obsługuje szukanie
CanWrite Ustalenie czy bieżący strumień obsługuje zapisywanie
Handle* Pobranie obsługi plików zapewnianej przez system operacyjny w postaci wskaźnika
IsAsync Ustalenie czy plik otwarto w sposób asynchroniczny
Length Pobranie długości strumienia w bajtach
Name Pobranie ścieżki bezwzględnej pliku otwartego przez obiekt "FileStream"
Position Pobranie lub ustawienie pozycji strumienia tak
SafeFileHandle Zwrócenie obiektu typu "SafeFileHandle" będącego wskaźnikiem do obsługi plików zapewnianej przez system operacyjny nie

* - uznane przez dokumentację za przestarzałe, lepiej używać "SafeFileHandle"

METODY KLASY "FILESTREAM"

A jakimi metodami może się pochwalić "FileStream" w języku C#? Wszystkie patrzały zerkają niżej :D:

NAZWA ZNACZENIE
BeginRead Rozpoczęcie asynchronicznej operacji odczytu.
BeginWrite Rozpoczęcie asynchronicznej operacji zapisu.
Close Zamknięcie strumienia (bardzo ważnym jest, żeby ZAWSZE na końcu wywołać tę metodę; inaczej plik może się nie ukazać w katalogu i nie będzie możliwe wykonywanie na nim operacji!).
Dispose Zwolnienie niezarządzanych zasobów (parametr "boolowski" pozwala także zwolnić te zarządzane).
EndRead Zakończenie asynchronicznej operacji odczytu.
EndWrite Zakończenie asynchronicznej operacji zapisu.
Flush Czyszczenie buforów strumienia i zapis danych bufora do pliku.
Lock Zabezpieczenie przed otwieraniem i zapisem do pliku przez inne procesy w systemie operacyjnym.
Read Odczyt bloku bajtów ze strumienia i zapis w podanym buforze.
ReadByte Odczyt pojedynczego bajta ze strumienia i przeniesienie pozycji o jeden bajt do przodu.
Seek Ustawienie pozycji strumienia na podaną wartość.
SetLength Ustawienie długości strumienia w bajtach.
Unlock Zdjęcie nałożonego wcześniej zabezpieczenia w wyniku wywołania metody "Lock".
Write Zapis sekwencji bajtów do strumienia i przejście do aktualnej pozycji o podaną liczbę bajtów do zapisu.
WriteByte Zapis pojedynczego bajta do aktualnej pozycji w strumieniu.

PRZYKŁAD KODU ŹRÓDŁOWEGO

Przedstawię dwa przykłady kodów. Jeden do zapisu danych, drugi do odczytu. "FileStream" w języku C# może być dopasowane zarówno do jednej czynności, jak i do drugiej:

ZAPIS DO PLIKU
string filename = "data.txt";
FileStream fs = new FileStream(filename, FileMode.Create);

for (byte i = 1; i <= 50; ++i)
{
	fs.WriteByte(i);
}

fs.Close();
ODCZYT Z PLIKU
string filename = "data.txt";
FileStream fs = new FileStream(filename, FileMode.Open);
int count = 50;
byte[] bytes = new byte[count];

fs.Read(bytes, 0, count);

for (byte i = 1; i <= count; ++i)
{
	//Console.WriteLine(fs.ReadByte());	// przy użyciu tej metody, tworzenie tablicy "bytes" i wywołanie metody "Read" nie będą potrzebne, można usunąć
	Console.WriteLine(bytes[i - 1]);
}

fs.Close();

Widać, że w drugim kodzie zawarłem obie instrukcje, a jedna z nich została zakomentowana. To dlatego, że odczyt za pomocą "FileStream" w języku C# można wykonać na dwa sposoby:

  • albo przy użyciu funkcji "ReadByte" odczytywać za każdym razem po małej porcji danych bajt po bajcie korzystając z pętli "for",
  • albo zainicjować tablicę typu "byte", przydzielić jej identyczną liczbę komórek (o tym mankamencie więcej za chwilę), wywołać metodę "Read" podając odpowiednie parametry (tablica bajtów, w której będą składowane dane, przesunięcie kursora o N bajtów i liczbę bajtów do wydobycia) i wyświetlać każdy argument, również przy użyciu pętli "for" albo jakiejś innej.

Ale to jeszcze nie koniec przedstawianego wątku...

SPOSÓB NA NIEREGULARNĄ LICZBĘ DANYCH

Jest mały problemik dotyczący wypisywania :(. Przy próbie odczytu musimy podać KONKRETNĄ liczbę bajtów! Sytuacja jednak nie jest do końca taka beznadziejna bowiem metoda "ReadByte" zwraca wartość -1, jeśli nie znajduje żadnych kolejnych danych do wydobycia. Stąd wniosek dla kumatych głów, że można wykorzystać pętlę "while" do odczytu nieregularnej wielkości danych wykorzystując w instrukcji warunkowej badanie wartości "ReadByte":

while (fs.ReadByte() != -1)
{
	// instrukcje
}

Ponieważ chcemy zrobić z danych użytek, lepiej jest przechować tymczasowo wydobyty bajt w zmiennej:

int i;

while ((i = fs.ReadByte()) != -1)
{
	// instrukcje
}

Metoda zwraca "integer", więc nie ma problemów z podstawieniem do liczby całkowitej "klasycznej". Jest jednak niestety bardziej druzgocąca wada. "FileStream" w języku C# obsługuje tylko bajty :O! W jedną i w drugą stronę wszystko kręci się wyłącznie w formie bajtowej. Nie mamy prawa wstawić sobie np. łańcucha znaków jako takiego (w jednym kawałku) i go sobie potem odczytać także jako łańcuch znaków. Wrócimy do tego dylematu później, wraz z zaprezentowaniem klasy pomocniczej, "StreamReader" ;).

Klasa "FileStream" w języku C#

Klasa "FileStream" jest zdolna wykonywać podstawowe operacje WEWNĄTRZ pliku. Ze względu na naturę danych, potrafi posługiwać się wyłącznie bajtami!


Dobiegła końca opowieść o klasie "FileStream" w języku C# przeznaczonej do "grzebania" w pliku. W kolejnej części o obsłudze plików zajmiemy się trybami dostępu do pliku.

PODOBNE ARTYKUŁY