Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаба №1 / books / csharp_ebook.pdf
Скачиваний:
77
Добавлен:
03.03.2016
Размер:
3.69 Mб
Скачать

Programmers Heaven: C# School

//Open the Reader over this file stream BinaryReader reader = new BinaryReader(fs);

//read different types of primitives to the file string name = reader.ReadString();

string ageString = reader.ReadString(); int age = reader.ReadInt32();

string wtString = reader.ReadString(); double weight = reader.ReadDouble();

//concatenate primitives into single string and display in the text box txtFileText.Text = name + ageString + age.ToString() + wtString + weight.ToString();

//close the file stream so that other streams may use it

reader.Close();

fs.Close();

}

Here we create the BinaryReader class’ object using the FileStream object. We then read the primitives previously written to the file. After reading all the data, we concatenate the primitives to a single string and display it in the text box. Finally we close the two streams. The important point to note here is that the primitives are read in the same order they were written.

Using StreamReader and StreamWriter to read and write text files

The classes StreamReader and StreamWriter are used to read and write text files. They have got useful methods like ReadLine() and ReadToEnd() to facilitate the reading and writing of text files. More than that, these streams can use different text encodings (like ASCII and Unicode) for reading and writing the files.

Author’s Note: You might have noticed that we haven’t gone into the details of specific classes in this section. The reason is that these classes are very similar to each other. All provide the same functionality and that is to read/write data from/to files.

They have a number of common and similar methods and some of them do not even serve any purpose. What you need to learn is which class should be used in which scenario. You can always see the description of individual methods of these classes in MSDN.

Once again, I will suggest not to leave the topic without practice just because it looks simple and easy. You should spend some hours playing with various streams for better understanding.

308

Programmers Heaven: C# School

Serialization and De-serialization

Serialization is the process of writing objects to the stream while De-serialization is the process of reading objects from the stream. Up until now, we have seen how to read/write primitive types to the streams but we haven’t read/written any explicit (user defined) type to the stream. There are certain points that must be clear before actually implementing the serialization.

The purpose of serializing or writing an object to a stream is to save its state. The state of an object is determined by its instance variables. Hence serializing an object means writing all of its member (or instance) variables (also called an object graph) to the stream. Methods or static members are not serialized or written to the stream.

You can serialize an object yourself by simply writing all of its member variables to the stream. When de-serializing, you would have to read all the member variables in the same sequence in which they were written. However this process of serializing and de-serializing has two major disadvantages:

It is a tedious job to write all the member variables yourself and it might become hectic if your class contains a lot of variables and if your class contains other user defined objects.

It is not the standard procedure. The person who is willing to de-serialize the object you serialized previously, would have to be aware of the sequence in which you wrote the member variables and must follow that sequence.

The Dot (.Net) framework takes care of these issues and provides binary and SOAP formatters using which you can serialize your object just by calling their Serialize() and Deserialize() methods.

There is a serious security issue connected with serialization. You might not want certain classes to be serialized to the stream or you might not want to serialize all of your member variables to the stream. For example, a web-application may not allow the UserInfo object to be serialized or its Password field to be serialized.

All the classes in .Net are un-serializable by default - that is they can not be written to a stream. You have to explicitly mark your class to be serializable using the [Serializable] attribute.

You can optionally mark a particular member variable (or field) as Non-Serialized by using the [NonSerialized] attribute to prevent the CLR from writing that field when serializing the object.

Author’s Note: We haven’t covered attributes in our C# School up till this issue. Attributes are a fantastic feature of C# that allow you to provide extra information about certain entities (like assemblies, classes, methods, properties and fields). The beauty of attributes lies in their power and equal amount of simplicity. If you are interested to learn about attributes, you will find MSDN very helpful.

Implementing Serialization and Deserialization – A simple example

Let’s create a console application that contains a serializable class. The application will serialize its object to a file and then deserialize it again from the file to another object. We will use a simple class that calculates the sum of two integer variables. The complete source code of the program is:

309

Programmers Heaven: C# School

using System;

 

 

using

System.IO;

// for FileStream

 

using

System.Runtime.Serialization.Formatters.Binary;

// for BinaryFormatter

namespace Compiler

{

class Test

{

static void Main()

{

Addition addition = new Addition(3, 4);

FileStream fs = new FileStream(@"C:\C-Sharp.txt", FileMode.Create); BinaryFormatter binForm = new BinaryFormatter();

Console.WriteLine("Serializing the object...."); binForm.Serialize(fs, addition);

fs.Position = 0; // move to the start of file

Console.WriteLine("DeSerializing the object....");

Addition sum = (Addition) binForm.Deserialize(fs);

int res = sum.Add();

Console.WriteLine("The sum of 3 and 4 is: {0}", res);

}

}

[Serializable] class Addition

{

private int num1; private int num2; private int result;

public Addition()

{

}

public Addition(int num1, int num2)

{

310

Programmers Heaven: C# School

this.num1 = num1; this.num2 = num2;

}

public int Add()

{

result = num1 + num2; return result;

}

public int Result

{

get { return result; }

}

}

}

The Addition class is very simple and has three private members. Note that we have marked the class with the [Serializable] attribute. Also note that we have included appropriate namespaces.

using

System;

 

 

Uusing System.IO;

// for FileStream

 

using

System.Runtime.Serialization.Formatters.Binary;

// for BinaryFormatter

 

 

 

 

In the Main() method we have created an instance of the Addition class. We have then created a file stream and serialized the object to this file using the BinaryFormatter class (We will come to THE BinaryFomatter later in the lesson).

FileStream fs = new FileStream(@"C:\C-Sharp.txt", FileMode.Create);

BinaryFormatter binForm = new BinaryFormatter();

Console.WriteLine("Serializing the object...."); binForm.Serialize(fs, addition);

This is all we need to do on our part when serializing an object. Deserializing is again similar but before deseializing we need to set the file pointer position to the start of the file

fs.Position = 0; // move to the start of file

Now we can deserialize the object from the stream using the same BinaryFormatter instance:

311

Соседние файлы в папке books