Using the new asynchronous file I/O operations

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.

How to do it...

Next we will see a simple example that we can extrapolate to a majority of these methods with ease.

  1. Create a new Visual Studio project of type Console Application named caAsyncIO.
  2. Add a using clause for System.IO:
    using System.IO;
  3. Copy the following base method:
    Private async static void CopyFolderContents() {
    String SourceFolder = @"C:PACKT2-CLRcaAsyncIOsource";
    String DestinationFolder = @"C:PACKT2-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);
        }
    }
  4. Then call it from the Main method:
    static void Main(string[] args)
    {
    CopyFolderContents();
    Console.ReadLine();
    }
  5. We just need to add the 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);
            }
        }
    }
  6. Then we can execute the FileStream I/O test. The execution of our application should give us the following result:
    How to do it...
  7. We will add the following two methods to implement a stream version of what we just did:
    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);
        }
    }
  8. We will only need to modify the CopyFolderContents() method by commenting the call to CopyFilesWithFileStreams and adding a call to CopyFilesWithStreams:
    await CopyFilesWithStreams(SourceFile, DestinationFile);
  9. If we execute it, the result will be exactly the same as before.

How it works...

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.

There's more...

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.

See also

  • The Understanding async and await in .NET 4.5 recipe.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset