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, 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:\temp\output.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." |