Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
(ebook) Visual Studio .NET Mastering Visual Basic.pdf
Скачиваний:
120
Добавлен:
17.08.2013
Размер:
15.38 Mб
Скачать

604 Chapter 13 WORKING WITH FOLDERS AND FILES

SW.WriteLine(itm.ToString)

Next

SW.Close()

FS.Close()

Notice that the Write method stores the item’s text, even though the item added to the control is an object. If you open the Items.txt file, you will read the following:

First Item {X=0,Y=0,Width=3,Height=3} {X=3,Y=4}

Last Item

Listing 13.17 clears the ListBox control and populates it again by reading the items from the file. (For more information on reading from a text file, see the discussion of the StreamReader object, in the following section.) Since the ListBox control’s items are stored as text, you can use the StreamWriter and StreamReader objects to write them to and read them from the file.

Listing 13.17: Reading an Items Collection From a Text File

Dim SR As StreamReader

Dim FS As FileStream

FS = New FileStream(“C:\Items.txt”, FileMode.Open) SR = New StreamReader(FS)

Dim itm As Object itm = SR.ReadLine()

While Not itm = Nothing ListBox1.Items.Add(itm) itm = SR.ReadLine()

End While

SR.Close()

FS.Close()

In the following sections, we’ll explore the BinaryWriter and BinaryReader objects, which are the equivalents of the StreamWriter and StreamReader objects for binary files. Because of the variety of the binary data types, these two objects provide many more methods than their text counterparts.

The BinaryWriter Object

To prepare your application to write to a binary file, you must set up a BinaryWriter object, with the statements shown here:

Dim BW As New BinaryWriter(FS)

where FS is a properly initialized FileStream object. You can also create a new BinaryWriter object directly on a file, with the following form of the constructor:

Dim BW As New StreamReader(path)

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

ACCESSING FILES 605

To specify the encoding of the text in the binary file, use the following form of the method:

Dim BW As New BinaryWriter(FS, encoding)

Dim BW As New BinaryWriter(path, encoding)

You can also specify a third argument with the size of the buffer to be used with the file input/output operations:

Dim BW As New BinaryWriter(FS, encoding, bufferSize)

Dim BW As New BinaryWriter(path, encoding, bufferSize)

Methods

The BinaryWriter object exposes the following methods for manipulating binary files.

Close

This method closes the current BinaryWriter and releases any system resources associated with it.

Flush

This method clears all buffers for the current writer and writes all buffered data to the underlying file.

Seek

This method sets the position within the current stream.

Write

This method writes a value to the current stream. This method is heavily overloaded, but it accepts a single argument, which is the value to be written to the file. The data type of its argument determines how it will be written. The Write method can save all the base types to the file except for the Date and Object types.

WriteString

Where all other data types can be written to a binary file with the Write method, strings must be written with the WriteString method. This method writes a length-prefixed string to the file and advances the current position by the appropriate number of bytes. The string is encoded by the current encoding scheme, and the default value is UTF8Encoding.

You will find examples of using the Write and WriteString methods of the BinaryWriter object at the end of the following section, which describes the methods of the BinaryReader object.

The BinaryReader Object

The BinaryReader object reads data from a binary file. As you have seen, binary files may also hold text, and the BinaryReader object provides the ReadString method to read strings written to the file

by the BinaryWriter.WriteString method.

To use the methods of the BinaryReader object in your code, you must first create an instance of the object. The BinaryReader object is associated with a FileStream object, and the simplest form of its constructor is

Dim BR As New BinaryReader(streamObj)

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

606 Chapter 13 WORKING WITH FOLDERS AND FILES

where streamObj is the FileStream object. You can also specify the character encoding scheme to be used with the BinaryReader object, using the following form of the constructor:

Dim BR As New BinaryReader(streamObj, encoding)

If you omit the encoding argument, the default UTF8Encoding will be used.

Methods

The BinaryReader object exposes the following methods for accessing the contents of a binary file.

Close

This method is the same as the Close method of the StreamReader object. It closes the current reader and releases the underlying stream.

PeekChar

This method returns the next available character from the stream without repositioning the current pointer. The character read is returned as an integer, or –1 if there are no more characters to be read from the stream. The name of the method doesn’t quite comply with the BinaryReader object, but here’s why. Peeking at the next byte makes sense only if the next byte is a character. Reading the first byte of a Double value, for example, wouldn’t help you much. A character is usually stored in a single byte (ASCII text), but it can also be stored in two bytes (Unicode text). The PeekChar method knows how many bytes it must read from the text (they’re determined by the current encoding), and it always returns a character, regardless of its size in bytes. The PeekChar method’s return value is an integer, not a character.

The Read Methods

The BinaryReader object exposes methods for reading the same base data types you can write to a file through the BinaryWriter object. Each method returns a value of the corresponding type (the ReadBoolean method returns a Boolean value, and so on) and only a single value of this type. To read multiple values of the same type, you must call the same method repeatedly. The various methods for reading the base data types from the file are briefly described in Table 13.7.

Table 13.7: The Read Methods of the BinaryReader Object

Value

Effect

ReadBoolean

Reads and returns a True/False value.

ReadByte

Reads and returns a single byte.

ReadBytes(byteArray, count)

Reads and returns count bytes from the file and stores them into the Byte

 

array passed as the first argument.

ReadChar

Reads and returns a character. Depending on how text was stored in the file,

 

the ReadChar method may read one or two bytes (in the case of Unicode text) ,

 

but it always returns a character.

 

Continued on next page

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

 

ACCESSING FILES

607

 

 

 

 

 

 

Table 13.7: The Read Methods of the BinaryReader Object (continued)

 

 

Value

Effect

ReadChars(charArray, count)

Reads and returns count characters from the file and stores them in the char-

 

acter array specified as the first argument.

ReadDecimal

Reads and returns a Decimal value from the file.

ReadDouble

Reads and returns a Double value from the file.

ReadInt16

Reads and returns a short Integer (a 2-byte) value.

ReadInt32

Reads and returns an Integer (a 4-byte) value.

ReadInt64

Reads and returns a Long Integer (8-byte) value.

ReadSByte

Reads and returns a signed byte.

ReadSingle

Reads a Single (4-byte) value from the file.

ReadString

Reads and returns a string from the file. The string must be stored in the file

 

prefixed by its length. This is how the WriteString method stored strings to a

 

text file, so there’s nothing you have to do anything special from within your

 

code. If the string isn’t prefixed by its length, the ReadString method will

 

read a string with the wrong number of characters. The method will inter-

 

pret the first byte as the string’s length.

ReadUInt16

Reads and returns an unsigned short Integer (2-byte) value.

ReadUInt32

Reads and returns an unsigned Integer (4-byte) value

ReadUInt64

Reads and returns an unsigned long Integer (8-byte) value

 

 

 

 

To use these methods, you’re supposed to know the structure of the data stored in the file. A file with a price list, for example, contains the same items for each product. The first two fields are the product’s ID and description, followed by the product’s price, and other pieces of information, which are repeated for each product. Once you know the types of values stored in the file, you can call the appropriate methods to read the correct values. If you misread even a single value, none of the following values will be read correctly.

VB.NET at Work: The RecordSave Project

Let’s look at the code for saving structured information to a binary file. In this section, you’re going to build the RecordSave application, which demonstrates how to store a price list to a disk file and read it later from the same file. The main form of the application is shown in Figure 13.2. The Save Records button creates a few records and then saves them to disk. The Read Records button reads the records from the file and displays them on the ListBox control.

Each record of the price list contains the following fields:

The product’s ID (a String)

The product’s description (a String)

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

608Chapter 13 WORKING WITH FOLDERS AND FILES

The product’s price (a Single value)

The product’s availability (a Boolean value)

The minimum reorder quantity (an Integer value)

Figure 13.2

The RecordSave project demonstrates how to store records in a binary file.

The program saves each field as a separate entity, using the Write method of a BinaryStream object. Only the string is written to the file with the WriteString method, because we want to be able to read the string back with the ReadString method.

Since the price list contains many products, you will most likely store it in an array of custom Structures. The Product structure shown next is a simple, yet quite adequate, structure for our price list:

Structure Product

Dim ProdID As String

Dim prodDescription As String

Dim listPrice As Single

Dim available As Boolean

Dim minStock As Integer

End Structure

The code that writes the Structure to a binary file is shown in the Listing 13.18.

Listing 13.18: Saving a Record to a Binary File

Private Sub Button1_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles Button1.Click

Dim BW As BinaryWriter

Dim FS As FileStream

FS = New FileStream(“Records.bin”, System.IO.FileMode.OpenOrCreate, _

System.IO.FileAccess.Write)

BW = New BinaryWriter(FS)

BW.BaseStream.Seek(0, SeekOrigin.Begin)

Dim p As New Product()

Save first record p.ProdID = “100-A39”

p.prodDescription = “Cellular Phone with built-in TV”

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

ACCESSING FILES 609

p.listPrice = 497.99 p.available = True p.minStock = 40 SaveRecord(BW, p)

Save second record p = New Product()

p.ProdID = “100-U300”

p.prodDescription = “Wireless Handheld” p.listPrice = 315.5

p.available = False p.minStock = 12 SaveRecord(BW, p)

Save third record

p = New Product() p.ProdID = “ZZZ”

p.prodDescription = “Last Gadget” p.listPrice = .99

p.available = True p.minStock = 1000 SaveRecord(BW, p)

BW.Close()

FS.Close()

End Sub

The code of the SaveRecord() subroutine is shown in Listing 13.19. It accepts as arguments the BinaryWriter object that represents the binary file to which the data will be written and a Product structure to be saved to the file.

Listing 13.19: The SaveRecord() Subroutine

Sub SaveRecord(ByVal writer As BinaryWriter, ByVal record As Product) writer.Write(record.ProdID)

writer.Write(record.prodDescription)

writer.Write(record.listPrice)

writer.Write(record.available)

writer.Write(record.minStock) End Sub

To read the records stored in the file, set up a BinaryReader associated with the Records.bin file and call the appropriate Read method for each field of the record. Since we don’t know in advance how many records are in the file, we set up a loop that keeps reading one record at a time, while the current position (property Position of the FileStream object) is less than the length of the file (property Length of the FileStream object). Listing 13.20 is the code behind the Read Records button.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com