There are some brand new asynchronous methods for file operation I/O, which are clearly designed for providing resource-intensive work without blocking the main UI thread.
For I/O operations, we have some interesting methods such as ReadAsync
, WriteAsync
, CopyToAsync
, FlushAsync
, ReadLineAsync
, and ReadToEndasync
, which are implemented on stream classes and on classes that read and/or write to streams such as TextWriter
or TextReader
.
Next we will see a simple example that we can extrapolate to a majority of these methods with ease.
caAsyncIO
.using
clause for System.IO
:using System.IO;
Private async static void CopyFolderContents() { String SourceFolder = @"C:PACKT 2-CLRcaAsyncIOsource"; String DestinationFolder = @"C:PACKT 2-CLRcaAsyncIOdestination"; Console.WriteLine("Going to copy {0} files..", Directory.EnumerateFiles(SourceFolder).Count()); foreach (string SourceFile in Directory.EnumerateFiles(SourceFolder)) { String DestinationFile = DestinationFolder + SourceFile.Substring(SourceFile.LastIndexOf('')); Await CopyFilesWithFileStreams(SourceFile, DestinationFile); } }
Main
method:static void Main(string[] args) { CopyFolderContents(); Console.ReadLine(); }
CopyFilesWithFileStreams
method:Private async static Task CopyFilesWithFileStreams(StringStartFile, String DestinationFile) { using (FileStreamSourceFileStream = File.Open(StartFile,FileMode.Open)) { using (FileStreamDestinationFileStream = File.Create(DestinationFile)) { Await SourceFileStream.CopyToAsync(DestinationFileStream); Console.WriteLine("Copied the " + DestinationFile); } } }
FileStream
I/O test. The execution of our application should give us the following result:Private async static Task CopyFilesWithStreams(String StartFile, String DestinationFile) { using (StreamReader SourceStreamReader = File.OpenText(StartFile)) { using (StreamWriter DestinationStreamWriter = File.CreateText(DestinationFile)) { Await CopyFilesAsync(SourceStreamReader, DestinationStreamWriter); Console.WriteLine("Copied the " + DestinationFile); } } } Public async static Task CopyFilesAsync(StreamReader SourceReader, StreamWriter DestinationWriter) { char[] buffer = new char[0x1000]; int numRead; while ((numRead = await SourceReader.ReadAsync(buffer, 0,buffer.Length)) != 0) { Await DestinationWriter.WriteAsync(buffer, 0, numRead); } }
CopyFolderContents()
method by commenting the call to CopyFilesWithFileStreams
and adding a call to CopyFilesWithStreams
:await CopyFilesWithStreams(SourceFile, DestinationFile);
We have set up a system to copy all the files from one directory to another. Using the Directory.EnumerateFiles
method does the trick, and we just have to enumerate them and delegate the task to a copy
method with source and destination paths that include the filename.
Additionally, CopyFolderContents
has been declared async so we can use the await
operator inside it, and we do that with CopyFilesWithStreams
, the first method we implement to read and copy the file using FileStream
objects. We do it with nested using
, the first for opening the file with File.Open
and the second for creating and writing the destination file with File.Create
.
Finally we use the CopyToASync
asynchronous method to do the trick. Of course, we use the await
operator inside it.
Next, we implement the same functionality but with the StreamReader
and StreamWriter
objects. We do it in a similar way, that is, with the two nested using
clauses, one for the reader and the other for the writer.
For executing the reading and writing tasks, we implemented our own method that executes a while loop that reads and writes a buffer from the source stream into the destination stream until it finishes copying. For doing this, it uses the new ReadAsync
and WriteAsync
methods.
We have seen how to use some of the many available methods, and there are many more to explore, but anyway, the concepts and workings are similar to those we have just seen.