Working with File Streams

Every file on your hard drive is just a sequence of characters. Text-based files are usually human readable and the characters can be edited in a text editor, such as Notepad. Binary files, on the other hand, contain data used by a program. If you try to open a binary file (such as an EXE file) in Notepad, the displayed text will not make any sense. This is because each character represents a byte of data in a format known only to the user of the file. In the case of an EXE file, the bytes are used by the operating system to run a compiled program. (As we will soon see, XML provides a good way to store structured data in readable text format.)

→ For more on the Byte and other data types, see in Chapter 6, “Understanding Data Types,” p.143

The Microsoft .NET framework introduces some new classes designed to work with streams. Files on the disk drive can be thought of as streams of character data, but streams also can reside in memory or be accessed over a network. As we will see, it is very easy to use the .NET framework classes to read and write data to a stream sequentially. You can also seek to a specific point in the stream, if the particular stream supports seeking.

Reading and Writing Sequential Text Files

Although text files may seem really simple, sometimes you may not need the power of a database (not to mention the extra coding, configuration, and support files that go along with it). The StreamReader and StreamWriter classes are designed for dealing with text files in a sequential fashion. Sequential means that the file is accessed one byte after the other in sequence, rather than jumping to a specific location.

Tip

You can create batch files, FTP scripts, and many other simple file formats on the fly by using sequential text files.


You can process data in a sequential file a line at a time or by reading a specified number of characters. The following few lines of code read each line of a text file and print it in the Output window.

Dim TestFile As StreamReader 
Dim LineofText As String 

TestFile = File.OpenText(Directory.GetCurrentDirectory() & "quotes.txt") 
Do 
    LineofText = TestFile.ReadLine() 
    Debug.WriteLine(LineofText) 
Loop Until LineofText Is Nothing 
TestFile.Close() 

The code for processing a text file line by line is very simple: Simply open the file and repeatedly call the Readline method of the StreamReader class. Another method, Writeline, allows you to write a line of text to a file. The following example reads each line in a file and then writes the uppercase version to another file:

Dim TestFile As StreamReader 
Dim OutputFile As StreamWriter 
Dim LineofText As String 

TestFile = File.OpenText(Directory.GetCurrentDirectory() & "quotes.txt") 
OutputFile = File.AppendText(Directory.GetCurrentDirectory() &_ 
"output.txt") 

While TestFile.Peek() <> -1 
    LineOfText = testfile.ReadLine() 
    OutputFile.WriteLine(LineOfText.ToUpper) 
End While 

TestFile.Close() 
OutputFile.Close() 

There are a couple of differences in the code examples for reading and writing a text file. First, notice we opened the file with the File.AppendText method, rather than the File.OpenText method. Appending means adding to a file, so the AppendText method will either add to an existing file or create the file if it does not exist. Repeatedly calling this function will cause the output.txt file to grow in size. On the other hand, if you want to erase the output.txt file before writing, you can open the file with the CreateText method:

TestFile = File.CreateText("c:	empoutput.txt") 

Appending to a file is useful for creating a log file, as you will see later in this chapter. In the second code example, we changed the While loop to use the Peek function. The Peek function returns the character code for the next character in the file, without reading it. Normally, each call to the ReadLine method advances to the next line in the stream. By peeking at the next character, you can determine whether the read will actually return anything. Peek returns –1 once you have reached the end of the file you are reading.

Reading Binary Data Types

At the operating system level, a file is a series of bytes. The StreamReader and StreamWriter classes are designed to deal with these bytes as string data. However, the bytes in your file may not always represent characters of text, but instead be numbers. The .NET framework provides the BinaryReader and BinaryWriter classes to allow you to access this information in a file directly in the correct numerical format. Table 24.3 lists some of the available methods and their associated data types.

Table 24.3. Using the BinaryReader and BinaryWriter Classes
Method Names Data Types
Read Bytes or Characters
ReadBoolean Boolean values
ReadByte One Byte value
ReadBytes Array of Bytes
ReadChar One character
ReadChars Array of characters
ReadString String
ReadDecimal Decimal
ReadInt16 Short
ReadInt32 Integer
ReadInt64 Long

To demonstrate the BinaryReader class, we’ll read a text file, but this time using the Byte data type. You can process a file either a single byte at a time or by blocks in a size of your choosing. The code in Listing 24.5 reads a text file in blocks of 100 bytes. The bytes are converted to their ASCII character values and displayed in a text box.

Listing 24.5. FILESTREAM.ZIP—Read Bytes and Convert to String
Const BLOCK_SIZE As Integer = 100 

Dim TestFile As BinaryReader 
Dim BytesRead As Integer 
Dim ByteValues(BLOCK_SIZE) As Byte 
Dim StringValue As String 
Dim ASCIIConverter As System.Text.ASCIIEncoding 

'Open a File for Reading 
TestFile = New BinaryReader(File.Open("quotes.txt",_ 
IO.FileMode.Open, IO.FileAccess.Read)) 

'Read the file in byte blocks, converting bytes to ASCII 
BytesRead = TestFile.Read(ByteValues, 0, BLOCK_SIZE) 
ASCIIConverter = New System.Text.ASCIIEncoding() 
While BytesRead > 0 
    StringValue = ASCIIConverter.GetString(ByteValues, 0, BytesRead) 
    txtMessage.text &= StringValue 
    Array.Clear(ByteValues, 0, BLOCK_SIZE) 
    BytesRead = TestFile.Read(ByteValues, 0, BLOCK_SIZE) 
End While 

TestFile.Close() 

Using the BinaryReader class is more involved than the StreamReader class, but it offers more flexibility if you are working with Byte data. Listing 24.5 also demonstrates the relationship between text files and bytes; characters are stored in a text file using an encoding standard. The ASCII encoding stores a character per byte, whereas the Unicode encoding requires two bytes (and contains more characters). For more information, see the help topic entitled “Encoding.”

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.86.56