Unformatted text preview:

I/OC# ProgrammingFebruary 21I/O•Up until now, the only reading/writing to the file system wehave seen is by way of settings files•We will now look at:•Navigating directories•Binary file I/O•Text file I/O•Asynchronous I/O•Serialization•The classes we need for I/O are in the System.IO namespacePart IDirectories/PathsDirectories•The Directory class provides static methods for creatingdirectories and navigating the file system•The DirectoryInfo class provides information about adirectory – including creation time, last access time, etc.•We will look at a couple examples that walk the file systemand print directories and filesAn aside – string literals•As usual with string literals, in C# the backslash and otherspecial characters need to be escaped•For example:"C:\\Users\\Ravi"would be the path of a Windows directory•There are many occasions when we would rather thecharacters be taken verbatim (like when we are dealing w ithfile paths, which have a lot of backslashes)•Prefixing a string literal with @ results in the characters of thestring being parsed as-is•For example:@"C:\Users\Ravi"Printing top-level directory structurevoid PrintDirectoryStructure() {DirectoryInfo di = new DirectoryInfo(@"C:\");Console.WriteLine(di.Name);foreach (DirectoryInfo d in di.GetDirectories()) {Console.WriteLine(" " + d.Name);}}Printing project directory structure•There are a few ways to get the path from which the programis being run:•Directory.GetCurrentDirectory()•Environment.CurrentDirectory•Application.StartupPath•If the program is running in the default loc ation where it wasbuilt, the path will b e som ething like..\bin\Debug•Since most of the contents of the project directory are acouple levels up, we can navigate relative to this startupdirectoryDirectoryInfo di = new DirectoryInfo(Directory.GetCurrentDirectory());di = di.Parent.Parent;Printing project directory structurevoid PrintProjectStructure() {DirectoryInfo di = new DirectoryInfo(Directory.GetCurrentDirectory());di = di.Parent.Parent;RecPrintDir(di, 1);}void RecPrintDir(DirectoryInfo di, int depth) {string indent = "";for (int i = 0; i < depth; i++)indent += " ";Console.WriteLine(indent + di.Name + "/");foreach (DirectoryInfo d in di.GetDirectories())PrintDir(d, depth + 1);foreach (FileInfo f in di.GetFiles())Console.WriteLine(indent + f.Name);}Part IIReading and writing dataReading and writing data•We now begin looking at reading and writing data to files•For all examples, we will place our input and output files inthe startup directory of the application•Ie, in the Debug folder of the projectBinary I/O•If we know that a particular file is text, we can use specializedclasses to operate on it•In the general case, however, a file is just an array of bytes•The most general way to read and w rite files is using theStream class•We will look at an example that copies the contents of onefile to another•Here we will not worry ab out exceptions that can be thrown –but I/O exceptions should be handled in practice!static void CopyFile() {string dir = Directory.GetCurrentDirectory();Stream istream =File.OpenRead(dir + @"\testfile.txt");Stream ostream =File.OpenWrite(dir + @"\testfile2.txt");byte[] buffer = new byte[1024];int bytesRead = istream.Read(buffer, 0, 1024);while (bytesRead > 0) {ostream.Write(buffer, 0, bytesRead);bytesRead = istream.Read(buffer, 0, 1024);}istream.Close();ostream.Close();}Binary I/O•The Stream class gives complete control over how to accessthe file: where to read/write from, the e xact number of bytesto manipulate at a time•The downside to calling Stream’s Read() and Write()methods is that these disk operations are only performedwhen explicitly statedBuffered streams•Instead, we can use buffered streams, which decide how muchdata to read and write to the disk and when•Using the BufferedStream class makes reads and writesmore efficient•Since it may have already fetched more data from disk thanpreviously requested, a Read() might only have to readin-memory data instead of going to the disk•Similarly, the buffered stream may c hoose to not immediatelywrite all the contents of a Write() to disk, instead waitingfor a better time•We need to make only a few changes to our previous exampleto make use of buffered streamsstatic void CopyFile() {string dir = Directory.GetCurrentDirectory();Stream istream =File.OpenRead(dir + @"\testfile.txt");Stream ostream =File.OpenWrite(dir + @"\testfile2.txt");BufferedStream bistream = new BufferedStream(istream);BufferedStream bostream = new BufferedStream(ostream);byte[] buffer = new byte[1024];int bytesRead = bistream.Read(buffer, 0, 1024);while (bytesRead > 0) {bostream.Write(buffer, 0, bytesRead);bytesRead = bistream.Read(buffer, 0, 1024);}bistream.Close();bostream.Flush();bostream.Close();}Buffered streams•Notice the call to Flush() on the output stream•Since the buffered stream may not write the data to diskimmediately, we need to e xplicitly make sure they have beenwritten before we exit•If there is still data in the buffer waiting to get written, simplyclosing the buffer will not write these to diskText I/O•If we know that the bytes of a file are to be interpreted ascharacters, we can use another type of stream•The StreamReader and StreamWriter classes allow readingand writing of entire lines of text with a s impler methodinterfacestatic void CopyFile() {string dir = Directory.GetCurrentDirectory();StreamReader istream =new StreamReader(dir + @"\testfile.txt");StreamWriter ostream =new StreamWriter(dir + @"\testfile2.txt", false);String text;do {text = istream.ReadLine();ostream.WriteLine(text);} while (text != null);istream.Close();ostream.Close();}Text I/O•Note that the boolean flag in the StreamWriter constructorsignifies whether or not to append to the file if it already exists•Again, we can make use of a buffered stre am to improveefficiency•Instead of passing the file path as a s tring to theStreamReader and StreamWriter constructors, pass themBufferedStream objectsAsynchronous I/O•All of the examples we have seen so far performedsynchronous I/O•You c an also make asynchronous I/O requests•That is, you can start an I/O operation and then continueexecuting some other logic•When the file operation is complete, a callback delegate canbe invokedAsynchronous I/O•Instead of using a Stream’s Read() method, you use theBeginRead() method:inputStream.BeginRead(buffer, // array of


View Full Document

Penn CIS 399 - CIS 399 LECTURE NOTES

Download CIS 399 LECTURE NOTES
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view CIS 399 LECTURE NOTES and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view CIS 399 LECTURE NOTES 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?