Object Oriented Programming Files and Streams Dr. Mike Spann
Contents Introduction Introduction Sequential file I/O Sequential file I/O Classes File and Directory Classes File and Directory Serialization Serialization Summary 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 formatting structure is placed on this byte stream, this is imposed by the application 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 ( ) 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 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 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 Static methods of File
Classes File and Directory Static methods of File (cont)
Classes File and Directory Static methods of 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 (which displays the contents of a directory) As a simple example, we can use an OpenFileDialog box (which only allows files to be selected) or a FolderBrowserDialog (which displays the contents of a directory) We can then use the File or Directory classes to print information about the selected item We can then use the File or Directory classes to print information about the selected item For a file we print the file size and 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); }
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 Demos\Files and Streams\FileTestForm.exe Demos\Files and Streams\FileTestForm.exe Demos\Files and Streams\FileTestForm.exe Classes File and Directory
Serialization It is easy to write the individual fields of a record object to a file 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 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) We can output each field of this record to a file (either text or binary)
Serialization StudentInfo Name Address ID number Course Info Record file string string int string
Serialization In this example, any program that needs to read the file needs to know the format of the data 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 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 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 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 StudentInfo Name Address ID number Course Info Record file StudentInfo object
Serialization To serialize an object, the object class needs to be marked with the [Serializable] attribute or needs to implement the ISerializable interface 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 Requires the System.Runtime.Serialization namespace Also we require a BinaryFormatter object to serialize/de-serialize the object before writing to or reading from file Also we require a BinaryFormatter object to serialize/de-serialize the object before writing to or reading from file It’s also possible to serialize objects using SOAP (simple object access protocol) or XML using the appropriate formatters
Serialization Example. A custom serializer GUI 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 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 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 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; }
using System.Windows.Forms; using System.IO; using System.Runtime.Serialization; using 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 to a binary file } private void button2_Click(object sender, EventArgs e) { //De - Serialize from a binary file back to a textbox } 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\SerializerTestForm.exe Demos\Files and Streams\SerializerTestForm.exe Demos\Files and Streams\SerializerTestForm.exe Demos\Files and Streams\SerializerTestForm.exe
Serialization
Binary serialization is limited as only.NET applications can deserialize the data stream 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 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 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 System; using System.Windows.Forms; using System.IO; using System.Xml; using 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 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 how we can use the File and Directory classes We have looked at object serialization to binary and XML We have looked at object serialization to binary and XML