370 likes | 466 Views
Object Oriented Programming. Files and Streams. Dr. Mike Spann m.spann@bham.ac.uk. 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
E N D
Object Oriented Programming Files and Streams Dr. Mike Spann m.spann@bham.ac.uk
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 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
FileStream object byte stream FileStream object byte stream Introduction
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{ FileStreamfromStream = new FileStream(args[0], FileMode.Open, FileAccess.Read); FileStreamtoStream = 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");} } }
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 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) • 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); } }
Classes File and Directory private void displayFileInfo(string fileName) { outputTextBox.Text += "\r\n\r\nFile: " + fileName + ":\r\n"; DateTimecreationTime = File.GetCreationTime(fileName); outputTextBox.Text += "Created: " + creationTime.ToString() + "\r\n"; DateTimelastModifiedTime = 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/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
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 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); FileStreamfilestream = 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(); StudentInfosi= 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
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 [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; } } • We need to insert XML tags into our StudentInfo class • Only public properties and fields can be serialized
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; StudentInfosi = new StudentInfo(name, address, courseInfo, id); XmlSerializerxmls = 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) { StudentInfosi; XmlSerializerxmls = 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(); } }
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