280 likes | 297 Views
Learn how to create, read, write, and manage files in C#. Understand sequential file processing, FileStream, StreamReader, and more. Use LINQ to search directories and classes like FileStream.
E N D
CSCI 3328 Object Oriented Programming in C# Chapter 11: Files and Streams Xiang Lian The University of Texas Rio Grande Valley Edinburg, TX 78539 xiang.lian@utrgv.edu
Objectives • In this chapter, you will • Learn how to create, read, write, and update files • Know how to use classes File and Directory to obtain information about files and directories on your computer • Learn how to use LINQ to search through directories • Get familiar with sequential-access file processing • Know how to use classes FileStream, StreamReader, StreamWriter, FileStream, and BinaryFormatter, as well as yield return
Introduction • Variables and arrays only offer temporary storage of data • Data are lost when the program terminates • In contrast, files are used for long-term storage place • Persistent data • Data are stored on secondary storage devices
Data Hierarchy • Bits • Characters (ASCII or Unicode) • Fields • Records • Files • Record key • Sequential file • Databases
Files and Streams • File as a sequential stream of bytes • Each file ends with an end-of-file marker • Windows keeps track of total number of bytes in a file • When a file is opened an object is created and a stream is associated with the object • Each program automatically gets 3 objects, Console.Out, Console.In and Console.Error
Classes File and Directory • Files are organized in directories • Class Directory provides capabilities for manipulating directories • Class File has static methods: • AppendText, Copy, Create, CreateText, Delete, Exists, GetCreationTime, GetLastAccessTime, GetLastWriteTime, Move, Open, OpenRead, OpenText, OpenWrite
Directory Class Static Methods • CreateDirectory • Delete • Exists • GetDirectories • GetFiles • GetCreationTime • GetLastAccessTime • GetLastWriteTime • Move
Create a File to Read/Write • Pre-defined class library • using System.IO; • StreamWriter (for text output) • StreamWriter outFile = newStreamWriter(fileName); • StreamReader (for text input) • StreamReader inFile = null; try{ using (inFile = newStreamReader(fileName)) { outputTextBox.AppendText(inFile.ReadToEnd());} } catch(IOException) { MessageBox.Show("Error reading from file", "File Error", MessageBoxButton.OK, MessageBoxIcon.Error); }
Write to the File • string fileName="test.txt"; • File.Exists(fileName) • true, if fileName exists • outFile.WriteLine("text"); • Other methods • File.GetCreationTime(fileName); • File.GetLastWriteTime(fileName); • File.GetLastAccessTime(fileName);
Read From the File • inFile.ReadLine();
Close the File • outFile.Close(); • inFile.Close();
Directory • Directory.Exists(Name); • true, if directory Name exists • string [] directoryList = Directory.GetDirectories(Name); • Obtain a list of files and directories
Searching Directories with LINQ • string currentDirectory; • currentDirectory = Directory.GetCurrentDirectory(); • string [] files = Directory.GetFiles(currentDirectory); • string [] directories=Directory.GetDirectories(currentDirectory); • var extensions = (from file in files selectPath.GetExtension(file)).Distinct(); foreach(var extension in extensions) { var extensionCount = (from file in files wherePath.GetExtension(file)==extension select file).Count(); }
Dictionary Class • A class Dictionary is a collection of key/value pairs • In namespace System.Collections.Generic • Dictionary <string, int> found = newDictionary <string, int>(); • Key is of string data type, and value is of intdata type • Methods • found.ContainsKey(extension) • true, if the directory contains a key for the extension • found.Add(extension, extensionCount); • found[extension] • Returns the value of the key "extension" • found.Keys • A collection of keys
Example of Deleting Files varbackupFiles = from file in files wherePath.GetExtension(file)==".bak" select file; foreach(var backup inbackupFiles) { DialogResult result = MessageBox.Show("Found backup file " + Path.GetFileName(backup) + ". Delete?", "Delete Backup", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { File.Delete(backup); // delete the file with name in "backup" found[".bak"]--; // decrement the counter if (found[".bak"] == 0) found.Remove(".bak"); // remove the key from dictionary } }
Create a Sequential File • In C# files, the concept of a "record" does not exist • Therefore, you have to create structured files by yourself • Use text and special characters to separate fields in the record
Example of Creating a Sequential File public class Record { public intAccount {get; set;} public string FirstName {get; set;} public string LastName {get; set;} public decimal Balance {get; set;} public Record() :this(0, string.Empty, string.Empty, 0M){} publicRecordSerializable (intacc, stringfName, stringlName, decimalbal) { Account = acc; FirstName = fName; LastName = lName; Balance = bal; } }
Example of Creating a Sequential File (cont'd) • FileStream output = newFileStream (fileName, FileMode.OpenOrCreate, FileAccess.Write); • StreamWriter fileWriter = newStreamWriter(output); • Record record = new Record(); • fileWriter.WriteLine(record.Account + "," + record.FirstName + "," + record.LastName + "," + record.Balance);
Reading Data From a Sequential-Access Text File • FileStream input = newFileStream(fileName, FileMode.Open, FileAccess.Read); • StreamReader fileReader = newStreamReader(input); • string inputRecord = fileReader.ReadLine(); • string[] inputFields; • if (inputRecord != null) { inputFields = inputRecord.Split(','); Record record = new Record(Convert.ToInt32(inputFields[0]), inputFields[1], inputFields[2], Convert.ToDecimal(inputFields[3])); }
Class BinaryFormatter • Class BinaryFormatter • Under namespace System.Runtime.Serialization.Formatters.Binary • Serializable(outFile, object) method • Write a serializable object to the output file • Serialization • In a class that is marked with [Serializable] attribute or that implements interface Iserializable, you must ensure that every instance variable in a class is also serializable • All simple-type variables, strings, and arrays (without containing references) are serializable
Example of RecordSerializable Class public class RecordSerializable { [Serializable] public intAccount {get; set;} public string FirstName {get; set;} public string LastName {get; set;} public decimal Balance {get; set;} publicRecordSerializable() :this(0, string.Empty, string.Empty, 0M){} publicRecordSerializable (intacc, stringfName, stringlName, decimalbal) { Account = acc; FirstName = fName; LastName = lName; Balance = bal; } }
Example of RecordSerializable Class (cont'd) BinaryFormatter formatter = new BinaryFormatter(); FileStream output = newFileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write); try{ RecordSerializable record = new RecordSerializable(); formatter.Serialize(output, record); } catch (SerializationException) { // … } catch (FormatException) { // … }
Reading and Deserializing Data From a Binary File BinaryFormatter reader = new BinaryFormatter(); FileStream input = newFileStream(fileName, FileMode.Open, FileAccess.Read); try{ RecordSerializable record = (RecordSerializable) reader.Deserialize(input); } catch (SerializationException) { input.Close(); }
Select Files from Chooser • Recall this topic in lecture slides of Chapter 8
Obtaining File Name From Chooser OpenFileDialog fDialog = new OpenFileDialog(); if (fDialog.ShowDialog() == DialogResult.OK) { fileName = (fDialog.FileName.ToString()); MessageBox.Show(fileName); }
Reading From a File StreamReaderofile = newStreamReader(fileName); while (ofile.Peek()!=-1) { stringoneline = ofile.ReadLine(); MessageBox.Show(oneline,"Reading From File.."); string[] items = oneline.Split(','); onePerson.fName = items[0]; onePerson.lName = items[1]; onePerson.GPA = Convert.ToSingle(items[3]); onePerson.Tele = items[2]; friendsList.Add(onePerson); } ofile.Close();
Writing to the File StreamWriter outfile = new StreamWriter(fileName); foreach (Info person in friendsList) outfile.WriteLine(person.fName+","+person.lName+","+person.Tele+","+Convert.ToString(person.GPA)); outfile.Close();