Vous êtes sur la page 1sur 37

Object Oriented Programming

Files and Streams

Contents
Introduction
Sequential file I/O
Classes File and Directory
Serialization
Summary

Introduction

Most applications require data to be stored in files

Spreadsheets

Word processing

etc

C# has an extensive set of classes for handling files of


various types

These are to be found in the System.IO namespace

Associated with files is the general concept of streams


which can be applied to both files and networks

Introduction

In C#, streams are simply sequences of bytes


No formattng structure is placed on this byte
stream, this is imposed by the appliction
We can read a byte stream from an input stream
object
We can write a byte stream to an output stream
object
The input and output stream objects are created
from class FileStream

Introduction
FileStream object
byte stream

FileStream object
byte stream

Sequential file I/O

There are many classes in the FCL for file


handling
FileStream is the basic file for handling I/O
from binary files
The constructor opens a stream object and
specifies the filename and file access (read,
write etc)
It provides a Read() and Write() method
Its normal to enclose file handling code in a
try{} catch{} clause to catch any exceptions
thrown

Sequential file I/O


using System;
using System.IO;

class FileCopy
{
public static void Main(String[] args){
try{
FileStream fromStream =
new FileStream(args[0], FileMode.Open,
FileAccess.Read);

FileStream toStream =
new FileStream(args[1], FileMode.Create,
FileAccess.Write);

Byte[] buffer = new Byte[fromStream.Length];

fromStream.Read(buffer, 0, buffer.Length);
toStream.Write(buffer, 0, buffer.Length);
}
catch
{
Console.WriteLine("Usage: FileCopy [FromFile]
[ToFile]");
}
}
}

Sequential file I/O

FileStream.Read() and FileStream.Write() are for


binary files
Data is stored in files as bytes which is efficient
but not humanly readable
A text file consists of information stored in
humanly readable form
For example the number 150 would be stored as
1 5 0 instead of the binary representation of
150 (10010110)
C# has a number of classes (descended from the
abstract TextReader and TextWriter classes) for
handling text i/o

Sequential file I/O

For text files, classes StreamReader and


StreamWriter are provided
These are derived from TextReader and
TextWriter
They use the familiar ReadLine() and WriteLine()
methods for doing formatted I/O
Note that the Console class has StreamReader and
StreamWriter objects and uses their ReadLine()
and WriteLine() methods for doing console-based
I/O

using System;
using System.IO;
class CreateTextFile
{
public static void Main(String[] args)
{
try
{
FileStream toStream =
new FileStream(args[0], FileMode.Create, FileAccess.Write);
StreamWriter fileWriter = new StreamWriter(toStream);
for (int i = 0; i < 10; i++)
fileWriter.WriteLine("i= " + i);
fileWriter.Close();
toStream.Close();
FileStream fromStream =
new FileStream(args[0], FileMode.Open, FileAccess.Read);
StreamReader fileReader = new StreamReader(fromStream);
for (int i = 0; i < 10; i++)
{
String input = fileReader.ReadLine();
Console.WriteLine(input);
}
}
catch{Console.WriteLine("Usage: CreateTextFile OutputFile");
}
}

Sequential file I/O

Classes File and Directory


Classes File and Directory allow an application
to obtain information about files and directories
stored on disc
Each class contains a large set of static methods
for both manipulation and information gathering
These classes could be the basis of a hard disc
scanning application to determine usage and
the amount of available storage space

Classes File and Directory

Classes File and Directory

Classes File and Directory

Classes File and Directory


As a simple example, we can use an
OpenFileDialog box (which only allows files
to be selected) or a FolderBrowserDialog
We can then use the File or Directory classes
to print information about the selected item
For a file we print the file size an d last
modified date
For a directory, we print its contents

using System;
using System.Windows.Forms;
using System.IO;
public partial class FileTestForm1 : Form
{
public FileTestForm1()
{
InitializeComponent(); }
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
string fileName = openFileDialog1.FileName;
if (File.Exists(fileName))
displayFileInfo(fileName);
}
private void displayFileInfo(string fileName)
{
// Displays file information }
private void displayDirectoryInfo(string pathName)
{
// Displays directory information }
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
}
private void button2_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
string pathName = folderBrowserDialog1.SelectedPath;
if (Directory.Exists(pathName))
displayDirectoryInfo(pathName);
}
}

Classes File and Directory


private void displayFileInfo(string fileName)
{
outputTextBox.Text += "\r\n\r\nFile: " + fileName + ":\r\n";
DateTime creationTime = File.GetCreationTime(fileName);
outputTextBox.Text += "Created: " + creationTime.ToString() + "\r\n";
DateTime lastModifiedTime = File.GetLastAccessTime(fileName);
outputTextBox.Text += "Last accessed: " + lastModifiedTime.ToString() + "\r\n";
}
private void displayDirectoryInfo(string pathName)
{
string[] directoryList;
directoryList = Directory.GetDirectories(pathName);
outputTextBox.Text += "\r\n\r\nDirectory Contents:\r\n";
// Output directory contents
for (int i = 0; i < directoryList.Length; i++)
outputTextBox.Text += directoryList[i] + "\r\n";
}

Classes File and Directory

Demos\Files and Streams\FileTestForm.exe

Serialization

It is easy to write the individual fields of a record object to a file


For example, we can create a record that stores information
about a student
Name
Address
ID number
Course enrolled for
etc
We can output each field of this record to a file (either text or
binary)

Serialization

Record file
string string int string

StudentInfo
Name
Address
ID number
Course Info

Serialization

In this example, any program that needs to read the file needs to
know the format of the data
2 strings, an int and then a string
Also whether each item is on a separate line
Object serialization allows complete objects to be read or written
with a single statement
A serialized object is an object represented as a sequence of bytes
Information is stored about the data types of the objects instance
fields as well as their values
Allows the object to be reconstructed (de-serialized) from the
file

Serialization

Record file
StudentInfo object

StudentInfo
Name
Address
ID number
Course Info

Serialization

To serialize an object, the object class needs to be marked


with the [Serializable] attribute or needs to implement
the ISerializable interface
Requires the System.Runtime.Serialization namespace
Also we require a BinaryFormatter object to serialize/deserialize the object before writing to or reading from file
Its also possible to serialize objects using SOAP
(simple object access protocol) or XML using the
appropriate formatters

Serialization

Example. A custom serializer GUI

Serialization
The user inputs student info. details in the
corresponding textboxes on the left which through
the serialization will be stored in a binary file
The information in the binary file will be
deserialized and displayed in the right hand
textboxes
We will create a simple StudentInfo class and tag
it as Serializable

Serialization
[Serializable]
class StudentInfo
{
public string Name, Address, CourseInfo;
public int ID;
public StudentInfo()
{}
public StudentInfo(String n, String a, String ci, int id)
{
Name = n; Address = a; CourseInfo = ci;
ID = id;
}
}

Serialization
using
using
using
using

System.Windows.Forms;
System.IO;
System.Runtime.Serialization;
System.Runtime.Serialization.Formatters.Binary;

public partial class SerializerTestForm1 : Form


{
private String fileName = Directory.GetCurrentDirectory() + "\\output1.txt";
public SerializerTestForm1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Serialize textbox data so a binary file
}
private void button2_Click(object sender, EventArgs e)
{
//Serialize textbox data so a binary file
}
}

Serialization
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
String name = textBox1.Text;
String address = textBox2.Text;
int id = Convert.ToInt32(textBox3.Text);
String courseInfo = textBox4.Text;
StudentInfo s = new StudentInfo(name,address,courseInfo,id);
FileStream filestream = new FileStream(fileName, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(filestream, s);
filestream.Close();
button1.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
FileStream filestream2 = new FileStream(fileName,FileMode.Open);
BinaryFormatter bf2 = new BinaryFormatter();
StudentInfo si= new StudentInfo();
si = (StudentInfo)bf2.Deserialize(filestream2);
textBox8.Text = si.Name;
textBox7.Text = si.Address;
textBox6.Text = ""+si.ID;
textBox5.Text = si.CourseInfo;
filestream2.Close();
}

Serialization

Demos\Files and Streams\SerializerTestFor


m.exe

Serialization

Serialization
Binary serialization is limited as only .NET
applications can deserialize the data stream
For more general inter-operability especially across a
network, XML serialization is used
XML is text based and self describing and
universal
Comprised name/attribute pairs
XML serialization easy to implement and uses text
streams

Serialization
We need to insert XML tags into our
StudentInfo class
Only public properties and fields can be
serialized

[XmlRoot("studentInfo")]
public class StudentInfo
{
[XmlAttribute("name")] public string Name;
[XmlAttribute("address")] public string Address;
[XmlAttribute("course")] public string CourseInfo;
[XmlAttribute("id")] public int ID;
public StudentInfo()
{ }
public StudentInfo(String n, String a, String ci, int id)
{
Name = n; Address = a; CourseInfo = ci;
ID = id;
}
}

using
using
using
using
using

System;
System.Windows.Forms;
System.IO;
System.Xml;
System.Xml.Serialization;

public partial class xmlSerializerTestForm1 : Form


{
private String fileName = Directory.GetCurrentDirectory() + "\\output1.xml";
public xmlSerializerTestForm1() {InitializeComponent();}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
String name = textBox1.Text;
String address = textBox2.Text;
int id = Convert.ToInt32(textBox3.Text);
String courseInfo = textBox4.Text;
StudentInfo si = new StudentInfo(name, address, courseInfo, id);
XmlSerializer xmls = new XmlSerializer(typeof(StudentInfo));
TextWriter w = new StreamWriter(fileName);
xmls.Serialize(w, si);
w.Close();
button1.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
StudentInfo si;
XmlSerializer xmls = new XmlSerializer(typeof(StudentInfo));
TextReader r = new StreamReader(fileName);
si = (StudentInfo)xmls.Deserialize(r);
textBox8.Text = si.Name;
textBox7.Text = si.Address;
textBox6.Text = "" + si.ID;
textBox5.Text = si.CourseInfo;
r.Close();
}
}

Serialization

Summary
We have seen how we can use streams to do
simple sequential file I/O for binary and
text files
We have looked at how we can use the File
and Directory classes
We have looked at object serialization to
binary and XML

Vous aimerez peut-être aussi