Pliki Podstawy programowania Prawie w każdym programie jest potrzebne napisanie kodu do czytania danych z pliku lub do zapisywaniu danych do pliku. Każde środowisko programowania zawiera środki do czytania i zapisywania danych do plików. Najmniejszej jednostką do przechowywania danych w pliku jest bajt. Rozmiar pliku jest podawany w bajtach lub w większych jednostkach: 1 Kbajt = 1024 bajtów, 1 Mbajt = 1024 * 1024 bajtów, 1 Gbajt = 1024 * 1024 * 1024 bajtów. Istnieją dwa typu plików: binarne i tekstowe. Plik binarny jest łańcuchem zapisów reprezentujących w postaci dwójkowej liczby lub znaki tekstowe. Zapisy mają jeden rozmiar, dlatego na podstawie podanego indeksu zapisu można obliczyć miejsce tego zapisu w pliku i przeczytać lub zapisać w to miejsce porcję danych. Plik tekstowy też jest łańcuchem zapisów, ale w postaci znakowej reprezentacji liczb i znaków tekstowych. Znaki zapisywane są w kodzie ASCII lub w kodzie UNICODE. Zapisy mają zwykle różne rozmiary i rozdzielone są albo dwoma znakami Początek wiersza (Powrót karetki) (kod 13) i Nowy wiersz (kod 10), albo tylko jednym znakiem Nowy wiersz (kod 10). Aby przeczytać lub zapisać element danych z zadanym indeksem, trzeba iść od początku pliku i liczyć zapisy. Oczywiste, że plik binarny daje zwykle większą prędkość działania programu, choć w przypadku szeregowego zapisywania i czytania zapisów pliki binarny i tekstowy nie różną się prędkością operacji. Przed operacją czytania lub zapisywania plik musi być otworzony za pomocą specjalnej instrukcji. Po zakończeniu operacji plik należy zamknąć.
1. Operacje z plikami w języku C Otwarcie i zamknięcie plików W języku C informacja o pliku i o stanie procesu czytania lub zapisywania może być przechowywana w obiekcie typu FILE. Wymagane prototypy funkcji i struktur są włączone w pliki nagłówkowe io.h i stdio.h. Odwołanie do tych plików należy dołączyć do tekstu programu: #include <io.h> #include <stdio.h> Alokacją obiektu typu FILE wykonuje funkcja fopen, która zwraca wskaźnik na strukturę FILE. Funkcja fopen ma następujący nagłówek: FILE* fopen(const char* nazwa_pliku, const char* tryb) Argument nazwa_pliku musi być nazwą pliku razem ze ścieżką. Zamiast nazwy pliku może być jedna z nazw standardowych urządzeni komputera: con - monitor, prn - drukarka, com - port szeregowy. Argument tryb określa tryb otwarcia pliku. Tryb jest opisywany ciągiem liter. Pierwsza litera określa operację nad plikiem: r - do odczytu pliku, który musi istnieć, w - do zapisywania pliku; jeżeli plik istnieje, to najpierw jest kasowany, a - do dopisywania pliku; jeżeli plik nie istnieje, to jest kreowany. Następna litera wskazuje na typ pliku: t - plik tekstowy, b - plik binarny. Jeżeli żadna z liter t, b nie występuje, to na typ pliku wskazuje wartość globalnej zmiennej _fmode. Na końcu wiersza - argumentu tryb można napisać jeszcze znak +, aby wskazać na możliwość tak odczytu, jak i zapisywania. Przykładowo FILE* pf=fopen( C:\\TEMP\\test.txt, rt+ ); /* jest otwierany istniejący plik tekstowy z możliwością aktualizacji*/ W przypadku nieudanego otwarcia pliku, funkcja fopen zwraca zerową wartość, co można wykorzystać dla sprawdzania czy plik istnieje?. Plik jest zamykany przy pomocy funkcji fclose, która ma następujący nagłówek: int fclose(file* wskaźnik_pliku) Na przykład: fclose(pf); /* zamyka plik ze wskaźnikiem pf */
Operacje z plikami tekstowymi W języku C do operacji z plikami tekstowymi służą licznie funkcje: int fgetc(file* pf) - odczyt pojedynczego znaku, int fputc(int znak, FILE* pf) - zapisywanie pojedynczego znaku, char* fgets(char* pbufor, int limit, FILE* pf) - odczyt wiersza, char* fputs(char* pbufor, FILE* pf) - zapisywanie wiersza. Ostatnim znakiem w pliku tekstowym jest znak EOF (ang. End Of File), co można wykorzystać dla wyjścia z cyklu odczytu pojedynczych znaków, na przykład: FILE* pf=fopen( C:\\TEMP\\test.txt, rt ); /* jest otwierany istniejący plik tekstowy*/ FILE* pf2=fopen( C:\\TEMP\\test2.txt, wt ); /* jest otwierany plik tekstowy do zapisywania*/ int znak; do {/*przepisywanie z pliku test.txt do pliku test2.txt*/ znak=fgetc(pf); if (znak!= EOF) { fputc(znak,pf2); } } while (znak!= EOF); fclose(pf2); /* zamyka plik i zapisuje znak EOF*/ fclose(pf); /* zamyka plik*/ Funkcja fgets przepisuje do bufora łańcuch znaków do pary znaków Początek wiersza i Nowy wiersz, ale nie więcej niż (limit-1) znaków, i dodaje do bufora znaki Nowy wiersz i \ 0. Funkcja fputs pobiera z bufora i zapisuje do pliku łańcuch znaków, który musi być zakończony w buforze znakami Nowy wiersz i \0. Przykład korzystania z funkcji fgets i fputs: FILE* pf=fopen( C:\\TEMP\\test.txt, rt ); /* jest otwierany istniejący plik tekstowy*/ FILE* pf2=fopen( C:\\TEMP\\test2.txt, wt ); /* jest otwierany plik tekstowy do zapisywania*/ char buf[128]; do {/*przepisywanie z pliku test.txt do pliku test2.txt*/ char* pch=fgets(buf,128,pf); if (pch!= 0) fputs(buf,pf2); } while (pch!= 0); fclose(pf2); /* zamyka plik i zapisuje znak EOF*/ fclose(pf); /* zamyka plik*/ Operacje z plikami binarnymi W języku C do operacji z plikami binarnymi są wykorzystywane następujące funkcje:
size_t fread(void* buf, size_t size, size_t nn, FILE* pf); size_t fwrite(void* buf, size_t size, size_t nn, FILE* pf); long ftell(file* pf); int fgetpos(file* pf, fpos_t* pos); int fseek(file* pf, long offset, int baza); int fsetpos(file* pf, fpos_t* pos); int fflush(file* pf); W środowisku Borland C++ Builder typ size_t jest zdefiniowany jako unsigned int, typ fpos_t - jako long. Funkcja fread czyta z pliku pf do bufora buf nn bloków bajtów rozmiarem size. Funkcja fwrite zapisuje do pliku pf z bufora buf nn bloków bajtów rozmiarem size. Obie funkcje zwracają liczbę przesłanych bloków, ale nie bajtów. Liczba przesłanych bajtów równa się (nn * size). Funkcje ftell i fgetpos podają pozycję wskaźnika pliku, a funkcje fseek i fsetpos ustawia wskaźnik pliku. Argument baza funkcji fseek może mieć następujące wartości: 0 - przemieszczenie offset należy liczyć od początku pliku, 1 - przemieszczenie offset należy liczyć od aktualnej pozycji wskaźnika pliku, 2 - przemieszczenie offset należy liczyć od końca pliku. Funkcja fflush opróżnia bufor pliku wyprowadzając dane do pliku. 2. Operacje z plikami w języku C++ W języku C++ do operacji z plikami można wykorzystywać strukturę FILE i funkcje języka C. Środowisko Borland C++ Builder W środowisku Borland C++ Builder jest klasa TFileStream do obsługi operacji z plikami. Metody klasy TFileStream są przystosowane do operacji z plikami binarnymi. W celu kreacji lub otwarcia istniejącego pliku należy zaalokować obiekt typu klasy TFileStream. Klasa ma konstruktor: fastcall TFileStream(const AnsiString FileName, Word Mode); Argument FileName jest nazwą pliku ze ścieżką. Argument Mode nadaje tryb otwarcia pliku i prawa dostępu do pliku. Wartość argumentu jest sumą logicznej binarnej opcji z dwóch grup. Opcje trybu otwarcia pliku mogą być następujące: fmcreate - system operacyjny musi otworzyć plik, a jeżeli plik istnieje, to skrócić jego do zera, fmopenread - system operacyjny musi otworzyć plik tylko do odczytu,
fmopenwrite - system operacyjny musi otworzyć plik tylko do zapisywania, fmopenreadwrite - możliwe są odczyt i zapisywanie danych. Opcje prawa dostępu do pliku mogą być następujące: fmshareexclusive - plik jest niedostępny dla innych aplikacji dopóty dopóki nie będzie zamknięty, fmsharedenywrite - inne aplikacje mogą tylko czytać dane z pliku, fmsharedenyread - inne aplikacje mogą tylko zapisywać dane do nie zamkniętego pliku. fmsharedenynone - inne aplikacje mogą czytać i zapisywać dane do nie zamkniętego pliku. Jeżeli plik nie może być otworzony, to system operacyjny produkuje wyjątek. Operacje z plikami binarnymi W języku C++ Builder w celu operacji z plikami binarnymi do klasy TFileStream dołączone są następujące metody i właściwości: virtual int fastcall Read(void *Buf, int NN); - odczyt do tablicy Buf nie więcej niż NN bajtów, virtual int fastcall Write(const void *Buf, int NN); - zapisywanie NN bajtów z tablicy Buf, virtual int64 fastcall Seek(const int64 Offs, TSeekOrigin Origin); - odczyt wiersza, property int64 Position - aktualna pozycja wskaźnika pliku, tj. odległość od początku pliku. property int64 Size - rozmiar pliku, ale tej właściwości nie można ustawić. Do metody Seek powinny być przekazane przemieszczenie Offs i opcja kierunku Origin, która może mieć jedną z wartości: - sofrombeginning - przemieszczenie od początku pliku, - sofromcurrent - przemieszczenie od aktualnej pozycji w pliku, - sofromend - przemieszczenie od końca pliku (przemieszczenie Offs musi być nie dodatnie). Środowisko Visual C++ W środowisku Visual C++ do operacji z plikami mają zastosowanie funkcje API (ang. Application Programming Interface) Win32. Tworzenie lub otwarcie pliku Funkcja API Win32 CreateFile tworzy lub otwiera plik. HANDLE CreateFile( LPCTSTR lpfilename, DWORD dwdesiredaccess, DWORD dwsharemode, LPSECURITY_ATTRIBUTES lpsecurityattributes, DWORD dwcreationdisposition, DWORD dwflagsandattributes, HANDLE htemplatefile );
Argumenty funkcji: lpfilename - adres nazwy pliku ze ścieżką, dwdesiredaccess tryb dostępu do pliku: GENERIC_READ do odczytu, GENE- RIC_WRITE do zapisu, które można połączyć operatorem, dwsharemode tryb dostępu do pliku ze strony innych aplikacji (można ustawić na 0), lpsecurityattributes adres struktury SECURITY_ATTRIBUTES z informacjami o zabezpieczeniach (można ustawić na 0), dwcreationdisposition tryb otwarcia pliku: CREATE_ALWAYS kreacja nowego pliku, OPEN_EXISTING otwarcie istniejącego pliku, dwflagsandattributes dodatkowe atrybuty (można ustawić na 0), htemplatefile deskryptor pliku tymczasowego (można ustawić na 0). Funkcja zwraca deskryptor (HANDLE) pliku, który należy stosować w funkcjach plikowych. Zamknięcie pliku Do zamknięcia pliku służy funkcja API Win32 CloseHandle. BOOL CloseHandle( HANDLE hobject ); Funkcja CloseHandle ma argument: hobject deskryptor pliku. Zapisywanie do pliku Do zapisywania do pliku służy funkcja API Win32 WriteFile. BOOL WriteFile( HANDLE hfile, LPCVOID lpbuffer, DWORD nnumberofbytestowrite, LPDWORD lpnumberofbyteswritten, LPOVERLAPPED lpoverlapped ); Funkcja WriteFile ma argumenty: hfile deskryptor pliku. lpbuffer adres bufora z danymi, nnumberofbytestowrite ilość bajtów do zapisywania, lpnumberofbyteswritten adres zmiennej do przechowywania ilości zapisanych bajtów, lpoverlapped adres struktury OVERLAPPED z informacją o nadpisaniu (można ustawić na 0). Funkcja zwraca ilość faktyczne zapisanych bajtów. Odczyt z pliku Do odczytu z pliku służy funkcja API Win32 ReadFile. BOOL ReadFile( HANDLE hfile, LPVOID lpbuffer, DWORD nnumberofbytestoread, LPDWORD lpnumberofbytesread, LPOVERLAPPED lpoverlapped ); Funkcja ReadFile ma argumenty:
hfile deskryptor pliku. lpbuffer adres bufora do przyjmowania danych, nnumberofbytestoread ilość bajtów do odczytu (rozmiar buforu), lpnumberofbytesread adres zmiennej do przechowywania ilości odczytanych bajtów, lpoverlapped adres struktury OVERLAPPED z informacją o nadpisaniu (można ustawić na 0). Funkcja zwraca (przez rejestr EAX) ilość faktyczne odczytanych bajtów. Przemieszczenie w pliku Do przemieszczenia w pliku służy funkcja API Win32 SetFilePointer. DWORD SetFilePointer( HANDLE hfile, LONG ldistancetomove, PLONG lpdistancetomovehigh, DWORD dwmovemethod ); Funkcja SetFilePointer ma argumenty: hfile deskryptor pliku. ldistancetomove odległość (w bajtach) do wartości (2^32 2), lpdistancetomovehigh ten argument musi być równy 0, jeśli rozmiar pliku jest mniejszy niż (2^32 2), a jeśli rozmiar pliku jest większy niż (2^32 2), to ten argument musi być adresem 32-bitowej zmiennej, która razem z argumentem ldistancetomove tworzy 64-bitową odległość, dwmovemethod opcja wskazująca na regułę liczenia odległości: FILE_BEGIN odległość jest liczona od początku pliku, FILE_CURRENT odległość jest liczona od aktualnej pozycji, FILE_END odległość jest liczona od końca pliku. Funkcja zwraca (przez rejestr EAX) pozycję wskaźnika pliku. Jeśli rozmiar pliku jest większy niż (2^32 2), to argument lpdistancetomovehigh wskazuje na 32-bitową zmienną, która razem z zawartością rejestru EAX tworzy 64-bitową pozycję.
3. Operacje z plikami w języku Object Pascal W języku Object Pascal można zdefiniować zmienną plikową typu plikowego. Typ plikowy file opisuje plik z nieznanym typem jednostki. Typ plikowy file of typ_jednostki opisuje plik binarny z zadanym typem jednostki. Procedura AssignFile łączy zmienną plikową z konkretnym plikiem. Za pomocą procedury Reset można otworzyć plik dla odczytu, za pomocą procedury Rewrite - dla zapisywania, oraz za pomocą procedury Append - dla dopisywania. Do zamykania pliku służy procedura CloseFile, Przykład otworzenia pliku dla odczytu w środowisku Delphi w programie obsługującej formularz FormKoszty z obiektami OpenDialog1 i StringGrid1: var plikkoszty: file of Integer; var i, j, value: Integer; if OpenDialog1.Execute then AssignFile(plikKoszty,OpenDialog1.FileName); Reset(plikKoszty); try for i := 1 to 5 do for j := 1 to 5 do Read(plikKoszty,value); FormKoszty.StringGrid1.Cells[i,j]:=IntToStr(value); finally CloseFile(plikKoszty); Operacje z plikami tekstowymi W środowisku Delphi z językiem Object Pascal jest specjalny typ Text (lub TextFile). Do obsługi plików tekstowych typu Text są wykorzystywane procedury: - Eoln do sprawdzania, czy jest osiągnięty koniec pliku, - Read do odczytu sformatowanego tekstu, - Readln do odczytu wiersza tekstu, - Write do zapisu sformatowanego tekstu. - Writeln do zapisu wiersza tekstu. Przykład z przepisywaniem zawartości obiektu Memo1 do pliku i z powrotem do obiektu Memo1: var pliktest: Text; var i,nn: Integer; var str: string; if SaveDialog1.Execute then AssignFile(plikTest,SaveDialog1.FileName);
Rewrite(plikTest); try nn:= Memo1.Lines.Count; for i := 1 to nn do str:= Memo1.Lines[i-1]; Writeln(plikTest,str); finally CloseFile(plikTest); if OpenDialog1.Execute then AssignFile(plikTest,OpenDialog1.FileName); Reset(plikTest); try nn:=0; repeat if Eoln(plikTest)=False then Readln(plikTest,str); Memo1.Lines[nn]:=str + 'plus'; nn:=nn+1; end end until Eoln(plikTest)=True; finally CloseFile(plikTest); Operacje z plikami binarnymi W środowisku Delphi z językiem Object Pascal do operacji z plikami binarnymi jest przeznaczona klasa TStream. Do tej klasy należą metody: procedure ReadBuffer(var Buffer; Count: Longint); do odczytu do buforu Buffer bloku rozmiarem Count bajtów, procedure WriteBuffer(const Buffer; Count: Longint); do zapisu z buforu Buffer bloku rozmiarem Count bloku bajtów. function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual; do ustawienia pozycji w pliku. Do metody Seek powinny być przekazane przemieszczenie Offset i opcja kierunku Origin, która może mieć jedną z wartości: - sofrombeginning - przemieszczenie od początku pliku, - sofromcurrent - przemieszczenie od aktualnej pozycji w pliku, - sofromend - przemieszczenie od końca pliku (przemieszczenie Offs musi być nie dodatnie). Właściwości klasy TStream:
property Position: Int64; - podaje aktualną pozycją wskaźnika pliku, tj. odległość od początku pliku. property Size: Int64; - podaje rozmiar pliku. 4. Operacje z plikami w języku Visual Basic.NET W języku Visual Basic.NET dla operacji z plikami jest specjalna klasa FileStream. Kreacja lub otwarcie istniejącego pliku są związane z alokacją obiektu typu klasy File- Stream. Klasa ma wiele konstruktorów, z których część jest przedstawiona nizej: Public Sub New(ByVal path As String, ByVal mode As FileMode) Public Sub New(ByVal path As String, ByVal mode As FileMode, ByVal access As FileAccess) Public Sub New(ByVal path As String, ByVal mode As FileMode, ByVal access As FileAccess, ByVal share As FileShare) Public Sub New(ByVal path As String, ByVal mode As FileMode, ByVal access As FileAccess, ByVal share As FileShare, ByVal buffersize As Integer) Public Sub New(ByVal path As String, ByVal mode As FileMode, ByVal access As FileAccess, ByVal share As FileShare, ByVal buffersize As Integer, ByVal useasync As Boolean) Do wszystkich konstruktorów należy podać poprzez argument path nazwę pliku ze ścieżką. Argument mode nadaje tryb otwarcia pliku. Możliwe są następujące warianty: Append - system operacyjny musi otworzyć istniejący plik lub otworzyć nowy plik oraz ustawić pozycję w pliku na koniec, Create - system operacyjny musi otworzyć plik, a jeżeli plik istnieje, to skrócić jego do zera, CreateNew - system operacyjny musi otworzyć nowy plik, a jeżeli plik istnieje, to powstaje wyjątek IOException, Open - system operacyjny musi otworzyć istniejący plik, a jeżeli plik nie istnieje, to powstaje wyjątek FileNotFoundException, OpenOrCreate - system operacyjny musi otworzyć istniejący plik lub otworzyć nowy plik, Truncate - system operacyjny musi otworzyć istniejący plik i skrócić jego długość do zera, Argument access nadaje prawa do operacji z plikiem. Możliwe są następujące warianty: Read - do pliku nie można zapisywać danych, ReadWrite - możliwe są odczyt i zapisywanie danych, Write - do pliku można tylko zapisywać dane. Argument share nadaje prawa dostępu do pliku. Możliwe są następujące warianty: None - plik jest niedostępny dla innych aplikacji dopóty dopóki nie będzie zamknięty, Read - inne aplikacje mogą czytać dane z pliku, ReadWrite - inne aplikacje mogą czytać i zapisywać dane do nie zamkniętego pliku, Write - inne aplikacje mogą zapisywać dane do nie zamkniętego pliku.
Argument buffersize nadaje rozmiar bufora dla danych. Argument useasync nadaje możliwość asynchronicznego odczytu i zapisywaniu. Przykład: ' Generacja danych w celu zapisywania do pliku Dim writearray(100000) As Byte Dim randomgenerator As New Random () randomgenerator.nextbytes(writearray) Dim fstream As New FileStream("Test.dat", _ FileMode.Create, FileAccess.ReadWrite, _ FileShare.None, 4096, True) Operacje z plikami tekstowymi W języku Visual Basic.NET w celu odczytu tekstu można wykorzystać klasę StreamReader, która dziedziczy od klasy TextReader. Obiekt tej klasy można zaalokować za pomocą konstruktora Public Sub New(ByVal stream As Stream), tj. na bazie otwartego strumienia, lub z argumentem path - z nazwą pliku ze ścieżką: Public Sub New(ByVal path As String). W konstruktorach klasy StreamReader mogą być dodatkowe argumenty: ByVal encoding As Encoding, ByVal detectencodingfrombyteordermarks As Boolean. Argument encoding opisuje kodowanie tekstu (ASCII, UNICODE itp.). Argument detectencodingfrombyteordermarks wskazuje, czy jest na początku pliku informacja o kolejności bajtów przy kodowaniu tekstu. W klasie StreamReader są metody do odczytu z pliku tekstowego: Overrides Overloads Public Function Read() As Integer - do pojedynczego odczytu znaków, Overrides Public Function ReadLine() As String - do odczytu wiersza zakończonego znakiem \n lub znakami \r\n. Metoda Read zwraca -1, jeżeli nie ma znaków do odczytu. W przypadku końcu pliku metoda ReadLine zwraca wartość Nothing. W klasie StreamReader jest metoda do odczytu do końca pliku: Overrides Public Function ReadToEnd() As String
Przykład do odczytu tekstu z pliku tekstowego: Imports System Imports System.IO Imports System.IO.TextReader Imports System.IO.StreamReader Class Test Public Shared Sub Main() Try ' alokacja obiektu typu StreamReader Dim sr As StreamReader = New StreamReader "test.txt") Dim line As String Do line = sr.readline() ' Odczyt wiersza MessageBox.Show(line,"Wiersz",MessageBoxButtons.OK,_ MessageBoxIcon.Information) 'wiersz Loop Until line Is Nothing sr.close() Catch E As Exception MessageBox.Show("Błędny odczyt", "Komunikat", _ MessageBoxButtons.OK, MessageBoxIcon.Information) MessageBox.Show(E.Message, "Komunikat", _ MessageBoxButtons.OK, MessageBoxIcon.Information) End Try End Sub End Class W celu zapisu tekstu stosuje się klasa StreamWriter, która dziedziczy od klasy TextWriter. Obiekt tej klasy można zaalokować za pomocą konstruktora Public Sub New(ByVal stream As Stream), tj. na bazie otwartego strumienia lub z argumentem path - z nazwą pliku ze ścieżką: Public Sub New(ByVal path As String) W konstruktorach klasy StreamWriter mogą być dodatkowe argumenty: ByVal encoding As Encoding, ByVal append As Boolean, ByVal buffersize As Integer. Argument encoding opisuje kodowanie tekstu (ASCII, UNICODE itp.). Argument append wskazuje, czy dane dopisać do pliku. Argument buffersize nadaje rozmiar bufora. Do zapisywania pojedynczych znaków oraz wierszy teksty służą warianty metody Write z argumentami typu Char, Char() lub String. Znaki \r\n nowego wiersza są zapisywane przez właściwość NewLine.
Przykład z zapisywaniem tekstu do pliku tekstowego: Imports System Imports System.IO Imports System.IO.TextWriter Imports System.IO.StreamWriter Class Test Public Shared Sub Main() ' alokacja obiektu typu StreamWriter Dim sw As StreamWriter = New StreamWriter("Test.txt") sw.write("tekst ") sw.writeline("dla testowania zapisywania.") sw.writeline("-------------------") sw.write("data dzisiejsza: ") sw.writeline(datetime.now) sw.close() End Sub End Class Operacje z plikami binarnymi W języku Visual Basic.NET w celu odczytu danych z pliku binarnego jest wykorzystywana klasa BinaryReader. Konstruktor tej klasy potrzebuje referencji do strumienia otwartego przez klasę FileStream: Dim fs As FileStream = New FileStream("Test.dat", FileMode.Open, FileAccess.Read) Dim br As BinaryReader = New BinaryReader(fs) Po zakończeniu operacji z plikiem należy wywołać metody Close zastosowanych klas: fs.close() br.close() Do odczytu danych z pliku binarnego służą liczne metody klasy BinaryReader, które mają w nazwę słowo Read i typ danych, na przykład ReadInt32. Aby przeczytać wszystkie dane, należy śledzić za pozycją miejsca odczytu i porównywać z rozmiarem pliku: Dim fs As FileStream = New FileStream("Test.dat", FileMode.Open, FileAccess.Read) Dim br As BinaryReader = New BinaryReader(fs) Dim leng As Long = fs.length While fs.position < leng Dim liczba As Integer liczba = br.readint32() End While br.close() fs.close()
W celu zapisywania danych do pliku binarnego jest wykorzystywana klasa BinaryWriter. Konstruktor tej klasy też potrzebuje referencji do strumienia otwartego przez klasę FileStream: Dim fs As FileStream = New FileStream("Test.dat", FileMode.Create) Dim br As BinaryWriter = New BinaryWriter(fs) Do zapisywania danych w postaci binarnej służą liczne warianty metody Write z argumentami typu Integer, Double itp. Przykład zapisywania zawartości ListBox'a z liczbami: Dim fs As FileStream = New FileStream("Test.dat", FileMode.Create) Dim sw As BinaryWriter = New BinaryWriter(fs) Dim nn As Integer = ListBoxWejsciowe.Items.Count Dim i As Integer For i = 0 To nn - 1 Dim liczba As Integer liczba = CInt(ListBoxWejsciowe.Items(i)) sw.write(liczba) Next i sw.close() fs.close()