To work with a local disk file, you use the FileStream class, which lets you move data to and from the stream as arrays of bytes. To make it easier to read and write basic data types, you can use the methods of the BinaryReader and BinaryWriter classes, or the equivalent methods of the StreamReader and StreamWriter classes. All these classes wrap an underlying FileStream and provide methods that make it easier to read and write data in the appropriate format. The BinaryReader/Writer classes use the native form of the basic data types and produce binary files that are not readable by humans. The StreamReader/Writer classes convert basic data types into XML format and produce text files. All the classes work with any type of data, so the distinction between text and binary files is no longer as important as it used to be in classic VB. You can store numbers either as text (in XML format), or in their native format.
VB.NET supports traditional random access files, but it doesn't really need them. You can still create files that store structures, and access them by record numbers, as you did with previous versions of Visual Basic using the FileOpen and FileGet functions, but for the most part, the functionality of random access files has been replaced by XML and/or databases. If you are designing new applications and don't need compatible random access capability you should use the newer .NET capabilities.
No matter which class you decide to use to access a file, you must first create a FileStream object. There are several ways to do that. The simplest method is to specify the file and how it will be opened in the FileStream object's constructor, which has the following syntax:
Dim fStream As New FileStream(path, _
fileMode, fileAccess)
The path argument contains the full pathname of the file you want to open. The fileMode argument is a member of the FileMode enumeration (see Table 1) that determines how to open (or create) the specified file. The fileAccess argument is a member of the FileAccess enumeration: Read (for reading only), ReadWrite (for reading and writing), and Write (for writing only).determines the read/write access to the file.|
Append |
Opens an existing file and moves to the end of it, or creates a new file. Use this mode when the file is opened for writing |
|
Create |
Creates a new file if the specified file exists, or overwrites the existing file. |
|
CreateNew |
Creates a new file. If the path argument specifies an existing file, an exception will be thrown. |
|
Open |
Opens an existing file. If the path argument specifies a file that doesn't exist, an exception will be thrown. |
|
OpenOrCreate |
Opens the specified file if it exists, or creates a new one. |
|
Truncate |
Opens the specified file and resets its size to 0 bytes. |
Dim FS As New FileStream = IO.File.OpenWrite("c:\Stream.txt")
Another way to open a file is to use the OpenFile method of the OpenFileDialog and SaveFileDialog controls. With the OpenFile method of these two controls you need not specify any arguments; both methods open the file selected by the user in the dialog. The OpenFile method of the OpenFileDialog control opens the file in read-only mode, whereas the OpenFile method of the SaveFileDialog control opens the file in read/write mode.Write(buffer, offset, count)
The buffer argument is the array containing the bytes to be written to the file, offset is the index of the first byte you want to write from the array, and count is the number of bytes to write. The syntax of the Read method is identical, except that the Read method fills the array buffer with count characters from the file. Dim buffer() As Byte
Dim encoder As New System.Text.ASCIIEncoding()
Dim str As String = "This is a line of text"
ReDim buffer(str.Length - 1)
encoder.GetBytes(str, 0, str.Length, buffer, 0)
FS.Write(buffer, 0, buffer.Length)
Notice that you must resize the buffer array to the length of the string you want to convert. To convert an array of bytes returned by the FileStream.Read method, use the GetChars method of the encoder variable.
As you can see, converting data to and from byte arrays is cumbersome. To avoid the conversions and simplify your code, you can use the StreamReader/StreamWriter classes to access text files, and the BinaryReader/BinaryWriter classes to access binary files. The BinaryReader/BinaryWriter classes derive from the Stream class, because they write binary data (bytes) to an underlying stream, but the StreamReader/ StreamWriter classes derive from the TextReader/TextWriter classes respectively, and perform byte encoding conversions automatically.
To read data from a binary file, create an instance of the BinaryReader class. The BinaryReader class's constructor accepts one argumenta FileStream object representing the file you want to open. You obtain the FileStream by building on the ways you've already seen to open a file, such as the File.OpenRead or File.OpenWrite methods:
Dim BR As New IO.BinaryReader(IO.File.OpenRead(path))
The syntax for the BinaryWriter class's constructor is similar: Dim BW As New IO.BinaryWriter(IO.File.OpenWrite(path))
The BinaryWriter class exposes Write and WriteLine methods. Both methods accept any of the basic data types as arguments and write the data to the file (the WriteLine method appends a newline character to the end of the data). The BinaryReader class exposes numerous methods for reading data back. The class stores data values in their native format, with no indication of their type, so the program that reads them back should use the appropriate overloaded Read method. The following statements assume that BW is a properly initialized BinaryWriter object, and show how you might write a string, an integer, and a double value to a file: BW.WriteLine("A String")
BW.WriteLine(12345)
BW.WriteLine(123.456789999999)
To read the values back, you must use the appropriate methods of a properly initialized BinaryReader object: Dim s As String = BR.ReadString()
Dim i As Int32 = BR.ReadInt32()
Dim dbl As Double = BR.ReadDouble()
To access text files, use the StreamReader/StreamWriter classes. The methods are nearly identical. To write text to a file, use either the Write or the WriteLine method. To read the data back, use the Read, ReadLine or ReadToEnd methods. The Read method reads a single character from the stream, ReadLine reads the next text line (up to a carriage-return/line-feed) and ReadToEnd reads all the characters to the end of the file.
So far you've seen how to save simple data types to a file, and read them back. Most applications don't store their data in simple variables. Instead, they use complicated structures to store their data, such as arrays, ArrayLists, HashTables and so on. It's possible to store an entire array to a file with a process called serialization. To do that, you convert the array values to a sequence of bytes, which you can then store to a file. The opposite process is called deserialization.
Serialization is a big topic in .NET, but here's the basic information you need.. To save an object to file and read it back, you use the Serialize and Deserialize methods of the BinaryFormatter class. First, import the System.RunTime.Serialization.Formatters namespace into your project to avoid typing excessively long statements. The Formatters namespace contains the BinaryFormatter class, which knows how to serialize basic data types in binary format. Create an instance of the BinaryFormatter class and then call its Serialize method, passing two arguments: a writeable FileStream instance for the file where you want to store the serialized object, and the object itself:
Dim BinFormatter As New Binary.BinaryFormatter()
Dim R As New Rectangle(10, 20, 100, 200)
BinFormatter.Serialize(FS, R)
The Deserialize method of the BinaryFormatter class accepts a single argumenta FileStream instancedeserializes the object at the current position in the FileStream and returns it as an object. You usually cast the deserialized object to the proper type with the CType function. For example, the following statement returns the serialized Rectangle object saved in the preceding code snippet: Dim R As New Rectangle()
R = CType(BinFormatter.Deserialize(FS), Rectangle)
You can also persist objects in text format using the XmlFormatter object. To do so, add a reference to the System.Runtime.Serialization.Formatters.Soap namespace with the Project> Add Reference command. After doing that, you can create an instance of the SoapFormatter object, which exposes the same methods as the BinaryFormatter object, but serializes objects in XML format. The following statements serialize a Rectangle object in XML format: Dim FS As New IO.FileStream("c:\Rect.xml", IO.FileMode.Create, IO.FileAccess.Write)
Dim XMLFormatter As New SoapFormatter()
Dim R As New Rectangle(8, 8, 299, 499)
XMLFormatter.Serialize(FS, R)
Double-click the file in which the Rectangle object was persisted to open it with Internet Explorer, as shown in Figure 1.
In the last section of the article you'll find code prototypes for the file operations you're likely to use most frequently. The simplest, and most common, operation is moving text in and out of text files. Binary files are not commonly used to store individual values; instead, modern applications most often use them to store objects, collections of objects, and other machine-readable data. In the following sections you'll find code examples for each of these scenarios.
Writing and Reading Text Files
To save text to a file, create a StreamReader object based on a FileStream object for the specific file and then call its Write method passing the text to be written to the file as argument. The following statements prompt the user to specify a file name with a SaveFileDialog instance, and then write the contents of the TextBox1 control to the selected file:
SaveFileDialog1.Filter = _
"Text Files|*.txt|All Files|*.*"
SaveFileDialog1.FilterIndex = 0
If SaveFileDialog1.ShowDialog = DialogResult.OK Then
Dim FS As FileStream = SaveFileDialog1.OpenFile
Dim SW As New StreamWriter(FS)
SW.Write(TextBox1.Text)
SW.Close()
FS.Close()
End If
OpenFileDialog1.Filter = _
"Text Files|*.txt|All Files|*.*"
OpenFileDialog1.FilterIndex = 0
If OpenFileDialog1.ShowDialog = DialogResult.OK Then
Dim FS As FileStream
FS = OpenFileDialog1.OpenFile
Dim SR As New StreamReader(FS)
TextBox1.Text = SR.ReadToEnd
SR.Close()
FS.Close()
End If
Dim BinFormatter As New Binary.BinaryFormatter()
Then create a FileStream instance based on the file where you want to serialize the object: Dim FS As New System.IO.FileStream("c:\test.txt", IO.FileMode.Create)
After creating the BinFormatter and the FS variables, call the Serialize method to serialize any serializable framework object: R = New Rectangle(rnd.Next(0, 100), _
rnd.Next(0, 300), rnd.Next(10, 40), _
rnd.Next(1, 9))
BinFormatter.Serialize(FS, R)
To serialize your own objects, add the Serializable attribute to the class: <Serializable()> Public Structure Person
Dim Name As String
Dim Age As Integer
Dim Income As Decimal
End Structure
P = New Person()
P.Name = "Joe Doe"
P.Age = 35
P.Income = 28500
BinFormatter.Serialize(FS, P)
BinFormatter.Serialize(FS, New Rectangle _
(0, 0, 100, 200))
To deserialize the Person object, create a BinaryFormatter object, call its Deserialize method and then cast the method's return value to the appropriate type. The Deserialize method deserializes the next available object in the stream. Dim P As New Person()
P = BinFormatter.Serialize(FS, Person)
Dim R As New Rectangle
R = BinFormatter.Serialize(FS, Rectangle)
Dim FS As New System.IO.FileStream _
("c:\test.txt", IO.FileMode.Create)
Dim BinFormatter As New Binary.BinaryFormatter()
Dim P As New Person()
Dim Persons As New ArrayList
P = New Person()
P.Name = "Person 1"
P.Age = 35
P.Income = 32000
Persons.Add(P)
P = New Person()
P.Name = "Person 2"
P.Age = 50
P.Income = 72000
Persons.Add(P)
BinFormatter.Serialize(FS, Persons)
FS = New System.IO.FileStream _
("c:\test.txt", IO.FileMode.OpenOrCreate)
Dim obj As Object
Dim P As Person(), R As Rectangle()
Do
obj = BinFormatter.Deserialize(FS)
If obj.GetType Is GetType(Person) Then
P = CType(obj, Person)
' Process the P objext
End If
Loop While FS.Position < FS.Length - 1
FS.Close()
FS = New System.IO.FileStream("c:\test.txt", IO.FileMode.OpenOrCreate)
Dim obj As Object
Dim Persons As New ArrayList
obj = CType(BinFormatter.Deserialize(FS), ArrayList)
FS.Close()
To connect to a remote Web server and request a file, you must create a WebRequest object and call its GetResponse method. The GetResponse method returns a Stream object, which you can use to read the remote file almost as if it were local. The following statements create a WebRequest object, which represents a request you make from within your application to a remote file. To create a WebRequest object call the Create method of the WebRequest class, passing the URL of the remote resource as argument. To retrieve the file, which in this case is the response from the remote Web server, you call the GetResponse method of the WebRequest object that represents the request. The GetResponse method returns a WebResponse object, which you can then pass as an argument to the StreamReader constructor. The following statements show how to request a file from a Web server and display it in a TextBox control:
Dim url As New Uri = _
"http://www.your_server.com/your_file.txt"
Dim Req As WebRequest
Req = WebRequest.Create(url)
Dim Resp As WebResponse
Try
Resp = Req.GetResponse
Catch exc As Exception
MsgBox(exc.Message)
Exit Sub
End Try
Dim netStream As StreamReader
netStream = New StreamReader(Resp.GetResponseStream)
TextBox2.Text = netStream.ReadToEnd
Public Function Clone() As Person
Dim BinFormatter As New Binary.BinaryFormatter()
Dim memStream As New System.IO.MemoryStream()
BinFormatter.Serialize(memStream, Me)
memStream.Position = 0
Return CType(BinFormatter.Deserialize _
(memStream), Person1)
End Function
Dim P1 As New Person
Dim P2 As New Person
P1.Name = "my name"
P1.Age = 35
P1.Income = 40000
P2 = P1.Clone()
Note that if you assign P2 to P1, both variables will point to the same object and every change you make to P1 will also affect P2. By cloning an object, you have created two instances of the Person class and you can manipulate them individually.
| DevX is a division of Jupitermedia Corporation © Copyright 2007 Jupitermedia Corporation. All Rights Reserved. Legal Notices |