Home

File Processing

Documents and Files

Introduction

When creating a webpage, you open an application and start typing. In the same way, you can use a graphics application to draw. The object you are using is called a document. After working on a document for a while, you can save it.

Introduction to File Processing and Definitions

A file is a series of bytes of data that are arranged in a particular manner to produce a usable document. For greater management, files can be stored in a parent object called a directory or a folder. A file has a size, which is the number of bits it uses to store its values. To manage it, a file has a location also called a path that specifies where and/or how the file can be retrieved. Also, for better management, a file has attributes (characteristics) that indicate what can be done on the file or that provide specific information that the programmer or the operating system can use when dealing with the file.

Streams

File processing consists of creating, storing, and/or retrieving the contents of a file from a recognizable medium. A stream is the technique or means of performing file processing. The most fundamental piece of information a file must have is a name.

Once the user has created a file, whether the file is empty or not, the operating system assigns basic pieces of information to it. Once a file is created, it can be opened, updated, modified, renamed, etc.

File Streaming Prerequisites

Introduction

To support file processing, the .NET Framework provides the System.IO namespace that contains many different classes to handle almost any type of file operation. Therefore, to perform file processing, you can include the System.IO namespace in your project.

The parent class of file processing is Stream. With Stream, you can store data to a stream or you can retrieve data from a stream. Stream is an abstract class used as the parent of the classes that actually implement the necessary operations. You will usually use a combination of classes to perform a typical operation.

The Name of a File

A webpage visitor may need to create a new file, to open an existing file, or to perform a routine operation on a file. You must specify the name of the file. You can do this by declaring a String variable but most classes used to create a stream can take a string that represents the file.

The Path to a File

When creating or saving a file, you must provide a complete or relative path to the file. A path is a string. The sections of a complete path string are separated by a backslash. For example, a path can be made of a folder followed by the name of the file. A path can also indicate that the file will be created in a folder that itself is inside of another folder. In this case, remember that the names of folder must be separated by backslashes.

The Server Map Path

To assist you in specifying the path to a file, the IIS's Server object, represented in the .NET Framework by the HttpServerUtility, is equipped with a method named MapPath. Its syntax is:

Public Function MapPath(ByVal path As String) As String

This method takes the name of a file or its path as a string.

The .NET Support for Files

Introduction

The primary support of a file as an object is provided by a .NET Framework class called File. This Shared class is equipped with various types of (static) methods to create, save, open, copy, move, delete, or check the existence of a file. As an alternative, the My object of the Visual Basic library provides additional functionalities. My includes the FileSystem object in the Computer object.

File Existence

One of the valuable operations that the File class can perform is to check the existence of the file you want to use. To let you check the existence of a file, the File class is equipped with a method named Exists. Its syntax is:

Public Shared Function Exists(ByVal path As String) As Boolean

To perform this operation using the FileSystem class from My, you can call its FileExists() method whose syntax is:

Public Function FileExists(ByVal file As String) As Boolean

In both cases, if the file exists, the method returns True. If the file doesn't exist, the method returns False.

File Creation

Besides checking the existence of the file, the File class can be used to create a new file. To support this operation, the File class is equipped with the Create() method that is overloaded with two versions as follows:

Public Shared Function Create(ByVal path As String) As FileStream
Public Shared Function Create(ByVal path As String, bufferSize As Integer) As FileStream

In both cases, the File.Create() method returns a Stream value, which is a FileStream value. As the File.Create() method indicates, it takes the name or path of the file as argument. If you know or want to specify the size, in bytes, of the file, you can use the second version.

To provide the same operation of creating a file, you can use the Open() method of the File class. It is overloaded in three versions as follows:

Public Shared Function Open(ByVal path As String, 
			    ByVal mode As FileMode) As FileStream
Public Shared Function Open(ByVal path As String, 
			    ByVal mode As FileMode, 
			    ByVal access As FileAccess) As FileStream
Public Shared Function Open(ByVal path As String, 
			    ByVal mode As FileMode, 
			    ByVal access As FileAccess, 
			    ByVal share As FileShare) As FileStream

Access to a File

In order to perform an operation on a file, you must specify the type of access that will be granted on the file. This access is specified using the FileAccess enumeration. The members of the FileAccess enumerator are:

File Sharing

When an operation must be performed on a file, you may have to specify how a file can be shared. This is done through the FileShare enumeration. The values of the FileShare enumeration are:

The Mode of a File

Besides the access to the file, you can specify the mode of access. This is done through the FileMode enumeration. The members of the FileMode enumeration are:

Fundamentals of File Streaming

Introduction

File streaming consists of performing one of the routine operations on a file, such as creating or opening it. The basic operation can be performed using a class called FileStream. The FileStream class is equipped with all necessary properties and methods. To use it, you must first declare a variable of it. The class is equipped with nine constructors.

One of the constructors of the FileStream class has the following syntax:

Public Sub New(ByVal path As String, ByVal mode As FileMode)

This constructor takes as its first argument the name of the file or its path. The second argument specifies the type of operation to perform on the file.

Stream Writing

A streaming operation is typically used to create a stream. Once the stream is ready, you can write data to it. The writing operation is performed through various classes. One of these classes is called BinaryWriter.

The BinaryWriter class can be used to write values of primitive data types (Char, Integer, Single, Double, etc). To use a BinaryWriter value, you can first declare its variable using one of the class's three constructors. The first constructor is the default. The second constructor has the following syntax:

Public Sub New(ByVal output As Stream)

This constructor takes as argument a Stream value, which could be a FileStream variable.

Most classes that are used to add values to a stream are equipped with a method called Write. This is also the case for the BinaryWriter class. This method takes as argument the value that must be written to the stream. The method is overloaded so that there is a version for each primitive data type.

Closing a Stream

After using a stream, you should (must) free the resources and make them available again to the operating system so that other services can use them. This is done by closing the stream.

To close a stream, you can can call the Close() method of the class(es) you were using.

Writing to a Stream

As mentioned already, the BinaryWriter class considers the values it has to write as binary values in the orders of integers, characters, and their variants. In some cases, you may want to write a block of text. To support this, the .NET Framework provides the StreamWriter class. StreamWriter is derived from the TextWriter class, which is the base class used to write a series of characters to a stream. To assist you with writing operations, the StramWriter class is equipped with various constructors.

If you had previously defined a FileStream object and you want to write values to it, you can use the following constructor of the StreamWriter class to create a stream:

Public Sub New (ByVal stream As Stream)

This method takes as argument a Stream-based variable, which could be a FileStream value.

If you do not want to use a Stream-based class, you can directly provide a file to the StreamWriter. To support this, the class is equipped with the following constructor:

Public Sub New(ByVal path As String)

This method takes as argument the name of, or a path to, a file.

After creating a StreamWriter object, you can write one or more values to it. To support this, the TextWriter class is equipped with the Write() method that the StreamWriter class inherits. The StreamWriter class itself is equipped with a method named WriteLine that is given in various versions, each version adapted to a particular data type. The Write() method writes text on a line and keeps the caret on the same line. The WriteLine() method writes a line of text and moves the caret to the next line.

Using My File System

By default, the FileStream class does not specify what operation is going to be performed on the file. If you are planning to create a new file and write values to it, you can call the OpenTextFileWriter() method of the FileSystem class of the My object. It comes in two versions whose syntaxes are:

Public Function OpenTextFileWriter(ByVal file As String, 
	                           ByVal append As Boolean) As System.IO.StreamWriter
Public Function OpenTextFileWriter(ByVal file As String,
				   ByVal append As Boolean, 
				   ByVal encoding As System.Text.Encoding) As System.IO.StreamWriter

The first argument is the name of, or the path to, the file that will receive the new values. The second argument specifies whether this is a new file or you are opening it to add new values to it. If this is a new file, pass the append argument as False. The encoding argument allows you to specify the type of text that you want to use.

This method returns a StreamWriter.

After creating the stream writer, you can then write values to it. To do this, you can call the WriteLine() method of the StreamWriter class. Once again, after using the stream writer, remember to close it.

Stream Reading

Binary Reading

As opposed to writing to a stream, you may want to read existing data from it. Before doing this, you can first specify your intent to the streaming class using the FileMode enumeration.

Once the stream is ready, you can get prepared to read data from it. To support this, you can use the BinaryReader class. This class provides two constructors. One of the constructors (the first) has the following syntax:

Public Sub New(ByVal input As Stream)

This constructor takes as argument a Stream value, which could be a FileStream object. After declaring a FileStream variable using this constructor, you can read data from it. To support this, the class provides an appropriate method for each primitive data type.

After using the stream, you should close it to reclaim the resources it was using. This is done by calling the Close() method.

Stream Reading

Besides the BinaryReader class that reads its values in binary format, the .NET Framework supports character reading through a class called StreamReader. The StreamReader class is based on the TextReader class. Like its counterpart the StramWriter class, StreamReader is equipped with various constructors. If you want to read values from a file, you can pass its name or path to the following constructor:

Public Sub New(ByVal path As String)

Alternatively, you can pass a FileStream object to the following constructor of the StreamReader class to create a stream:

Public Sub New(ByVal stream As Stream)

This method takes as argument a Stream-based variable, which could be a FileStream value. If/since you are planning to read from a stream, configure your file mode status appropriately.

After creating a StreamReader object, you can read data from the file. To support this, the TextReader class is equipped with the Write() method that the StreamReader class inherits. The StreamReader class itself is equipped with the ReadLine() method.

Using My File System

To read text from a file using the FileSystem class from My object, you can call the OpenTextFileReader() method. It comes in two versions whose syntaxes are:

Public Shared Function OpenTextFileReader(
   ByVal file As String) As System.IO.StreamReader

Public Shared Function OpenTextFileReader( 
   ByVal file As String, 
   ByVal encoding As System.Text.Encoding 
) As System.IO.StreamReader

The first argument is the name of, or the path to, the file that will receive the new values. The encoding argument allows you to specify the type of text that you want to use.

This method returns a StreamReader value. After creating the stream reader, you can then read values from it. To do this, you can call the ReadLine() method of the StreamReader class. Once again, after using the stream reader, remember to close it.

Exception Handling in File Processing

Finally

As mentioned already, resources must be allocate to perform file processing. We also know that, when the streaming is over, we can call the Close() method of the variable that was using resources. The creation and/or management of streams should be performed in a Try block to get ready to handle exceptions that would occur. Besides actually handling exceptions, you can use a special keyword to free resources. This keyword is Finally.

The Finally keyword is used to create a section of an exception. Like Catch, a Finally block cannot exist by itself. It can be created following a Try section. The formula to follow is:

try

Finally

End Try

The Finally section has a body of its own. Like Catch, the Finally section is created after the Try section. Unlike Catch, Finally never uses parameters. Unlike Catch, the Finally section is always executed. Because the Finally clause always gets executed, you can include any type of code in it but it is usually appropriate to free the resources that were allocated previously.

Of course, since the whole block of code starts with a Try section, it is used for exception handling. This means that you can add the necessary and appropriate Catch section(s) (but you don't have to).

The File Not Found Exception

The .NET Framework provides various Exception-oriented classes to deal with various types of exceptions that may occur when processing a file.

When a file operation must occur, if the file doesn't exist, the FileNotFoundException exception is thrown. To handle the FileNotFoundException exception, you can create its Catch clause.

The I/O Exception

During file processing, if something goes wrong but you don't know what caused an error, you can throw the IOException exception.

Files Operations - File Information

Introduction

The .NET Framework provides the FileInfo class that is equipped to handle all types of file-related operations including creating, copying, moving, renaming, or deleting a file. FileInfo is based on the FileSystemInfo class that provides information on characteristics of a file.

To assist you with finding information about a file, the FileSystem class from the My object is equipped with a method named GetFileInfo.

File Initialization

The FileInfo class is equipped with one constructor whose syntax is:

Public Sub New(ByVal fileName As String)

This constructor takes as argument the name of a file or its complete path.

As mentioned previously, to get information about a file, you can call the GetFileInfo() method of the FileSystem class from the My object. Its syntax is:

Public Shared Function GetFileInfo(ByVal file As String) As FileInfo

This shared method returns a FileInfo object. After calling this method, you can then use its returned value to get the information you want about the file.

File Creation

The FileInfo constructor is mostly meant only to indicate that you want to use a file, whether it exists already or it would be created. Based on this, if you execute an application that has only a FileInfo object created using the constructor as done above, nothing would happen.

To create a file, you have various alternatives. If you want to create one without writing anything in it, which implies creating an empty file, you can call the FileInfo.Create() method. Its syntax is:

Public Function Create As FileStream

This method simply creates an empty file. The FileInfo.Create() method returns a FileStream object. You can use this returned value to write any type of value into the file, including text. If you want to create a file that contains text, an alternative is to call the FileInfo.CreateText() method. Its syntax is:

Public Function CreateText As StreamWriter

This method returns a StreamWriter object. You can use this returned object to write text to the file.

File Existence

When you call the FileInfo.Create() or the FileInfo.CreateText() method, if the file passed as argument, or as the file in the path of the argument, exists already, it would be deleted and a new one would be created with the same name. This can cause an important file to be deleted. Therefore, before creating a file, you may need to check whether it exists already. To do this, you can check the value of the Boolean FileInfo.Exists property. This property holds a True value if the file exists already and it holds a False value if the file does not yet exist or it does not exist in the path.

Writing to a File

As mentioned earlier, the FileInfo.Create() and the FileInfo.CreateText() methods can be used to create a file but they don't write values to the file. To write values in the file, each method returns an appropriate object. The FileInfo.Create() method returns FileStream object. You can use this to specify the type of operation that would be allowed on the file. To write normal text to a file, you can first call the FileInfo.CreateText() method that returns a StreamWriter object.

As an alternative to Create() or CreateText(), if you want to create a file that can only be written to, you can call the FileInfo.OpenWrite() method. Its syntax is:

Public Function OpenWrite As FileStream

This method returns a FileStream that you can then use to write values into the file.

Appending to a File

You may have created a text-based file and written to it. If you open such a file and find out that a piece of information is missing, you can add that information to the end of the file. To do this, you can call the FileInfo.AppenText() method. Its syntax is:

Public Function AppendText As StreamWriter

When calling this method, you can retrieve the StreamWriter object that it returns, then use that object to add new information to the file.

Reading from a File

To support reading from a file, the FileInfo class is equipped with a method named OpenText(). Its syntax is:

Public Function OpenText As StreamReader

This method returns a StreamReader object. You can then use this object to read the lines of a text file.

If you want to open a file that can only be read from, you can call the FileInfo.OpenRead() method. Its syntax is:

Public Function OpenRead As FileStream

This method returns a FileStream that you can then use to read values from the file.

Routine Operations on Files

Opening a File

To support opening a file, the FileInfo class is equipped with the Open() method that is overloaded with three versions. Their syntaxes are:

Public Function Open(ByVal mode As FileMode) As FileStream
Public Function Open(ByVal mode As FileMode, 
		     ByVal access As FileAccess) As FileStream
Public Function Open(ByVal mode As FileMode, 
		     ByVal access As FileAccess, 
		     ByVal share As FileShare) As FileStream

You can select one of these methods, depending on how you want to open the file, using the options for file mode, file access, and file sharing. Each version of this method returns a FileStream object that you can then use to process the file. After opening the file, you can then read or use its content.

Deleting a File

To delete a file, you can call the FileInfo.Delete() method. Its syntax is:

Public Overrides Sub Delete

Copying a File

You can make a copy of a file from one directory to another. To do this, you can call the FileInfo.CopyTo() method that is overloaded with two versions. One of the versions has the following syntax:

Public Function CopyTo(ByVal destFileName As String) As FileInfo

When calling this method, specify the path or directory that will be the destination of the copied file.

When calling the first version of the FileInfo.CopyTo() method, if the file exists already, the operation would not continue and you would simply receive a message box. If you insist, you can overwrite the target file. To do this, you can use the second version of this method. Its syntax is:

Public Function CopyTo(ByVal destFileName As String,
		       ByVal overwrite As Boolean) As FileInfo

The first argument is the same as that of the first version of the method. The second argument specifies what action to take if the file exists already in the target directory. If you want to overwrite it, pass the second argument as true; otherwise, pass it as false.

Moving a File

Instead of copying, you can move a file from one directory to another. This operation can be performed by calling the FileInfo.MoveTo() method. Its syntax is:

Public Sub MoveTo(destFileName As String)

The argument to this method is the same as that of the CopyTo() method. After executing this method, the FileInfo object would be moved to the destFileName path.

Characteristics of a File

The Date and Time a File Was Created 

After a file has been created, the operating system makes a note of the date and the time the file was created. This information can be valuable in other operations such as search routines. You too are allowed to change this date and time values to those you prefer.

As mentioned already, the OS makes sure to keep track of the date and time a file was created. To find out what those date and time values are, you can access the get accessor of the FileSystemInfo.CreationTime property, which is of type DateTime.

Of course, by formatting the value, you can get only either the date or only the time.

If you don't like the date, the time, or both, that the OS would have set when the file was created, you can change them. To change one or both of these values, you can assign a desired DateTime object to the set accessor of the FileSystemInfo.CreationTime property.

The Date and Time a File Was Last Accessed 

To know the date and time that the file was last accessed, you can access the FileSystemInfo.LastAccessTime property, which is of type DateTime.

If you are interested to know the last date and time a file was modified, you can get the value of its FileSystemInfo.LastWriteTime property, which is of type DateTime.

The Name of a File

When reviewing or opening a file, to get its name, the FileInfo class is equipped with the Name property.

The Extension of a File

To know the extension of a file, you can access the value of the FileSystemInfo.Extension property.

The Size of a File

To get the size of a file, the FileInfo class is quipped with the Length property.

The Path to a File

The location of a file is referred to as its path or directory. The FileInfo class represents this path as the DirectoryName property.

Besides the FileInfo.Directoryname, to know the full path to a file, you can access its FileSystemInfo.FullName property.

The Attributes of a File

Attributes are characteristics that apply to a file, defining what can be done or must be disallowed on it. The Attributes are primarily defined by, and in, the operating system, mostly when a file is created. When the user accesses or opens a file, to get its attributes, you can access the value of its FileSystemInfo.Attributes property. This property produces a FileAttributes object.

When you create or access a file, you can specify or change some of the attributes. To do this, you can create a FileAttributes object and assign it to the FileSystemInfo.Attributes property.

FileAttributes is an enumeration with the following members: Archive, Compressed, Device, Directory, Encrypted, Hidden, Normal, NotContentIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, and Temporary.

Object Serialization and De-Serialization

Introduction to Serialization

Traditional file processing consists of saving individual values one at a time. Object serialization consists of saving a whole object as one instead of its individual values. In other words, a variable declared from a class can be saved to a stream and then the saved object can be retrieved later or on another computer. The .NET Framework supports two types of object serialization: binary and SOAP.

Introduction to Binary Serialization

Binary serialization works by processing an object rather than streaming its individual member variables. To use it, define an object and initialize it, or "fill" it, with the necessary values and any information you judge necessary. This creates a "state" of the object. It is this state that you prepare to serialize. When you save the object, it is converted into a stream.

To perform binary serialization, there are a few steps you must follow. When creating the class whose objects would be serialized, start it with the <Serializable> attribute. Here is an example:

<Serializable>
type Brokerage ... =
    ...

Before serializing an object, you should reference the System.Runtime.Serialization.Formatters.Binary namespace in your webpage. The class responsible for binary serialization is called BinaryFormatter:

Public NotInheritable Class BinaryFormatter
	Implements IRemotingFormatter,
		   IFormatter

This class is equipped with two constructors. The default constructor is simply used to create an object.

After declaring the variable, to actually serialize an object, call the Serialize() method of the BinaryFormatter class. The method is overloaded with two versions. One of the versions of this method uses the following syntax:

Public Sub Serialize(serializationStream As Stream,
		     graph As Object)

The first argument to this method must be an object of a Stream-based class, such as a FileStream object. The second argument must be the object to serialize. This means that, before calling this method, you should have built the object.

Here is an example of serializing an object:

<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Runtime.Serialization.Formatters.Binary" %>

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
<Serializable>
Public Class Brokerage
    Public Sub New(ByVal shares As Double, ByVal price As Double)
        Me.Shares = shares
        Me.Price = price
    End Sub

    Public Property Shares As Double
    Public Property Price As Double

    Public ReadOnly Property Principal as double
        Get
            Return Shares * Price
        End Get
    End Property

    Public ReadOnly Property Commission As Double
        Get
            If (Me.Price >= 0.0) And (Me.Price <= 2500.0) Then
                Return 26.25 + (Me.Price * 0.0014)
            ElseIf (Me.Price > 2500.0) And (Me.Price <= 6000.0) Then
                Return 45.0 + (Me.Price * 0.0054)
            ElseIf (Me.Price > 6000.0) And (Me.Price <= 20000.0) Then
                Return 60.0 + (Me.Price * 0.0028)
            ElseIf (Me.Price > 20000.0) And (Me.Price <= 50000.0) Then
                Return 75.0 + (Me.Price * 0.001875)
            ElseIf (Me.Price > 50000.0) And (Me.Price <= 500000.0) Then
                Return 131.25 + (Me.Price * 0.0009)
            Else ' If (Me.Price > 500000.0 Then
                Return 206.25 + (Me.Price * 0.000075)
            End If
        End Get
    End Property

    Public ReadOnly Property TotalInvestment As Double
        Get
            Return Me.Principal + Me.Commission
        End Get
    End Property
End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim principal = 0.0
    Dim commission = 0.0
    Dim stock As Brokerage
    Dim pricePerShare = 0.0
    Dim numberOfShares = 0.0

    numberOfShares = If(String.IsNullOrEmpty(txtNumberOfShares.Text), 0.00, txtNumberOfShares.Text)
    pricePerShare  = If(String.IsNullOrEmpty(txtPricePerShare.Text), 0.00, txtPricePerShare.Text)

    stock = New Brokerage(numberOfShares, pricePerShare)

    txtPrincipal.Text = FormatNumber(stock.Principal)
    txtCommission.Text = FormatNumber(stock.Commission)
    txtTotalInvestment.Text = FormatNumber(stock.TotalInvestment)
End Sub

Sub btnSaveClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim stock As Brokerage
    Dim pricePerShare = 0.0
    Dim numberOfShares = 0.0
    Dim fsStock As FileStream
    Dim bfStock As New BinaryFormatter()

    numberOfShares = If(String.IsNullOrEmpty(txtNumberOfShares.Text), 0.00, txtNumberOfShares.Text)
    pricePerShare  = If(String.IsNullOrEmpty( txtPricePerShare.Text), 0.00, txtPricePerShare.Text)

    If Not String.IsNullOrEmpty(txtFileName.Text) Then
        stock = New Brokerage(numberOfShares, pricePerShare)
        fsStock = New FileStream(Server.MapPath("series\" & txtFileName.Text), FileMode.Create, FileAccess.Write, FileShare.Write)

        bfStock.Serialize(fsStock, stock)
    End If
End Sub
</script>
<title>Brokerage Company</title>
</head>
<body>
<title>Brokerage Company</title>

<form id="frmCompany" runat="server">
<table>
  <tr>
    <td>Number of Shares:</td>
    <td><asp:TextBox id="txtNumberOfShares" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>Price Per Share:</td>
    <td><asp:TextBox id="txtPricePerShare" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td><asp:Button id="btnCalculate" Text="Calculate"
                               OnClick="btnCalculateClick" runat="server" /></td>
  </tr>
  <tr>
    <td>Principal:</td>
    <td><asp:TextBox id="txtPrincipal" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>Commission:</td>
    <td><asp:TextBox id="txtCommission" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>Total Investment:</td>
    <td><asp:TextBox id="txtTotalInvestment" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td style="text-align: right">
             <asp:Button id="btnSaveAs" Text="Save As"
                                OnClick="btnSaveClick" runat="server" /></td>
    <td><asp:TextBox id="txtFileName" Width="100px" runat="server" /></td>
  </tr>
</table>
</form>
</body>
</html>

Here is an example of testing the program:

Introduction to Binary Serialization Introduction to Binary Serialization
Introduction to Binary Serialization Introduction to Binary Serialization

De-Serialization

De-serialization is used to retrieve an object from a stream. To support this, the BinaryFormatter class is equipped with the Deserialize() method. Like Serialize(), the Deserialize() method is overloaded with two versions. One of them uses the following syntax:

Public Function Deserialize(ByVal serializationStream As Stream) As Object

This method takes as argument a Stream-based object, such as a FileStream variable, that indicates where the file is located. The Deserialize() method returns an Object object. As a goal, you want the Deserialize() method to produce the type of object that was saved so you can retrieve the values that the returned object holds. Because the method returns an Object value, you must cast the returned value to the type of your class. You can call the CType() function to perform the conversion.

Here is an example of deserializing an object:

<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Runtime.Serialization.Formatters.Binary" %>

<!DOCTYPE html>

<html>
<head runat="server">
<script runat="server">
<Serializable>
Public Class Brokerage
    Public Sub New(ByVal shares As Double, ByVal price As Double)
        Me.Shares = shares
        Me.Price = price
    End Sub

    Public Property Shares As Double
    Public Property Price As Double

    Public ReadOnly Property Principal as double
        Get
            Return Shares * Price
        End Get
    End Property

    Public ReadOnly Property Commission As Double
        Get
            If (Me.Price >= 0.0) And (Me.Price <= 2500.0) Then
                Return 26.25 + (Me.Price * 0.0014)
            ElseIf (Me.Price > 2500.0) And (Me.Price <= 6000.0) Then
                Return 45.0 + (Me.Price * 0.0054)
            ElseIf (Me.Price > 6000.0) And (Me.Price <= 20000.0) Then
                Return 60.0 + (Me.Price * 0.0028)
            ElseIf (Me.Price > 20000.0) And (Me.Price <= 50000.0) Then
                Return 75.0 + (Me.Price * 0.001875)
            ElseIf (Me.Price > 50000.0) And (Me.Price <= 500000.0) Then
                Return 131.25 + (Me.Price * 0.0009)
            Else ' If (Me.Price > 500000.0 Then
                Return 206.25 + (Me.Price * 0.000075)
            End If
        End Get
    End Property

    Public ReadOnly Property TotalInvestment As Double
        Get
            Return Me.Principal + Me.Commission
        End Get
    End Property
End Class

Sub btnCalculateClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim principal = 0.0
    Dim commission = 0.0
    Dim stock As Brokerage
    Dim pricePerShare = 0.0
    Dim numberOfShares = 0.0

    numberOfShares = If(String.IsNullOrEmpty(txtNumberOfShares.Text), 0.00, txtNumberOfShares.Text)
    pricePerShare  = If(String.IsNullOrEmpty(txtPricePerShare.Text), 0.00, txtPricePerShare.Text)

    stock = New Brokerage(numberOfShares, pricePerShare)

    txtPrincipal.Text = FormatNumber(stock.Principal)
    txtCommission.Text = FormatNumber(stock.Commission)
    txtTotalInvestment.Text = FormatNumber(stock.TotalInvestment)
End Sub

Sub btnSaveClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim stock As Brokerage
    Dim pricePerShare = 0.0
    Dim numberOfShares = 0.0
    Dim fsStock As FileStream
    Dim bfStock As New BinaryFormatter()

    numberOfShares = If(String.IsNullOrEmpty(txtNumberOfShares.Text), 0.00, txtNumberOfShares.Text)
    pricePerShare  = If(String.IsNullOrEmpty( txtPricePerShare.Text), 0.00, txtPricePerShare.Text)

    If Not String.IsNullOrEmpty(txtFileName.Text) Then
        stock = New Brokerage(numberOfShares, pricePerShare)
        fsStock = New FileStream(Server.MapPath("series\" & txtFileName.Text & ".stk"), FileMode.Create, FileAccess.Write, FileShare.Write)

        bfStock.Serialize(fsStock, stock)
    End If
End Sub

Sub btnOpenClick(ByVal sender As Object, ByVal e As EventArgs)
    Dim stock As Brokerage
    Dim fsStock As FileStream
    Dim bfStock As New BinaryFormatter()

    If Not String.IsNullOrEmpty(txtFileName.Text) Then
        fsStock = New FileStream(Server.MapPath("series\" & txtFileName.Text), FileMode.Open, FileAccess.Read, FileShare.Read)

        stock = CType(bfStock.Deserialize(fsStock), Brokerage)

        txtNumberOfShares.Text = FormatNumber(stock.Shares)
        txtPricePerShare.Text = FormatNumber(stock.Price)
        txtPrincipal.Text = FormatNumber(stock.Principal)
        txtCommission.Text = FormatNumber(stock.Commission)
        txtTotalInvestment.Text = FormatNumber(stock.TotalInvestment)
    End If
End Sub
</script>
<title>Brokerage Company</title>
</head>
<body>
<title>Brokerage Company</title>

<form id="frmCompany" runat="server">
<table>
  <tr>
    <td>Number of Shares:</td>
    <td><asp:TextBox id="txtNumberOfShares" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>Price Per Share:</td>
    <td><asp:TextBox id="txtPricePerShare" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>&nbsp;</td>
    <td><asp:Button id="btnCalculate" Text="Calculate"
                               OnClick="btnCalculateClick" runat="server" /></td>
  </tr>
  <tr>
    <td>Principal:</td>
    <td><asp:TextBox id="txtPrincipal" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>Commission:</td>
    <td><asp:TextBox id="txtCommission" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td>Total Investment:</td>
    <td><asp:TextBox id="txtTotalInvestment" Width="70px" runat="server" /></td>
  </tr>
  <tr>
    <td style="text-align: right">
             <asp:Button id="btnSaveAs" Text="Save As"
                                OnClick="btnSaveClick" runat="server" /></td>
    <td><asp:TextBox id="txtFileName" Width="100px" runat="server" />
            <asp:Button id="btnOpen" Text="Open"
                                OnClick="btnOpenClick" runat="server" /></td>
  </tr>
</table>
</form>
</body>
</html>

Here is an example of testing the program:

Introduction to De-Serialization Introduction to De-Serialization
Introduction to De-Serialization Introduction to De-Serialization

Details on Serialization

SOAP Serialization

The .NET Framework supports another technique of serialization referred to as SOAP (which stands for Simple Object Access Protocol). This technique is related to XML but you don't need to know anything about XML in order to use SOAP serialization.

Partial Serialization

You can make it possible to save only some parts of the class. When creating the class, to specify that a member cannot be saved, mark it with the <NonSerialized> attribute.

Implementing a Custom Serialized Class

To support serialization, the .NET Framework provides the ISerializable interface. You can create a class that implements this interface to customize the serialization process.

.NET Built-In Serialized Classes

The .NET Framework is filled with many classes ready for serialization. To know that a class is ready for serialization, when viewing its documentation (on the MSDN web site), check that it is marked with the [SerializableAttribute]. Here is an example of such as class:

The Serializable attribute of a built-in class

Some of these classes provide the properties and methods to create an object and directly save it. For some other classes, you must first create a class, mark it with the <Serializable> attribute, build an object of it, and then pass it to the .NET class.


Previous Copyright © 2002-2016, FunctionX Next