开发手册 欢迎您!
软件开发者资料库

.NET(C#)异步文件(Asynchronous File) I/O读写拷贝文件的方法及示代码

异步操作使您能在不阻塞主线程的情况下执行占用大量资源的 I/O 操作。 在 Windows 8.x 应用商店应用或桌面应用中一个耗时的流操作可能阻塞 UI 线程并让应用看起来好像不工作时,这种性能的考虑就显得尤为重要了。本文主要介绍通过异步文件(Asynchronous File) I/O读取文件,写入文件及拷贝文件到另一位置的方法及示例代码(CopyToAsync、StreamReader 和 StreamWriter)。

1、异步文件I/O

从 .NET Framework 4.5 开始,I/O 类型包括异步方法来简化异步操作。 异步方法在其名称中包括 Async ,例如 ReadAsync、 WriteAsync、 CopyToAsync、 FlushAsync、 ReadLineAsync和 ReadToEndAsync。 这些异步方法基于流类(例如 Stream、 FileStream和 MemoryStream)和用来向流中读出或写入数据的类(例如 TextReader 和 TextWriter)实现。

在 .NET Framework 4 和更早的版本中,您必须使用 BeginRead 和 EndRead 之类的方法来实现异步 I/O 操作。 这些方法仍然在 .NET Framework 4.5 中可用,从而支持传统的代码;但是,异步方法能帮助你更轻松地实现异步 I/O 操作。

C# 和 Visual Basic 分别具有两个用于异步编程的关键字:

  • Async (Visual Basic) 或 async (C#) 修饰符,您可以用来标记包含异步操作的方法。
  • Await (Visual Basic) 或 await (C#) 运算符,可以应用到异步方法的结果中。

如下面的示例所示,若要实现异步 I/O 操作,请把这些关键字和异步方法结合使用。 有关详细信息,请参阅使用 async 和 await 的异步编程 (C#) 或 使用 Async 和 Await 的异步编程 (Visual Basic)

2、进行文件拷贝

使用两个 FileStream 对象把文件从一个目录异步复制到另一个目录。 需要注意 Click 控件的 Button 事件处理程序具有 async 修饰符标记,因为它调用异步方法。

using System;using System.Threading.Tasks;using System.Windows;using System.IO;namespace WpfApplication{    public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();        }        private async void Button_Click(object sender, RoutedEventArgs e)        {            string StartDirectory = @"c:\Users\exampleuser\start";            string EndDirectory = @"c:\Users\exampleuser\end";            foreach (string filename in Directory.EnumerateFiles(StartDirectory))            {                using (FileStream SourceStream = File.Open(filename, FileMode.Open))                {                    using (FileStream DestinationStream = File.Create(EndDirectory + filename.Substring(filename.LastIndexOf('\\'))))                    {                        await SourceStream.CopyToAsync(DestinationStream);                    }                }            }        }    }}

3、通过StreamReader 和 StreamWriter读写实现文件拷贝

使用 StreamReader 和 StreamWriter 对象以异步方式读取和写入文本文件的内容。

private async void Button_Click(object sender, RoutedEventArgs e){    string UserDirectory = @"c:\Users\exampleuser\";    using (StreamReader SourceReader = File.OpenText(UserDirectory + "BigFile.txt"))    {        using (StreamWriter DestinationWriter = File.CreateText(UserDirectory + "CopiedFile.txt"))        {            await CopyFilesAsync(SourceReader, DestinationWriter);        }    }}public async Task CopyFilesAsync(StreamReader Source, StreamWriter Destination) {     char[] buffer = new char[0x1000];     int numRead;     while ((numRead = await Source.ReadAsync(buffer, 0, buffer.Length)) != 0)     {        await Destination.WriteAsync(buffer, 0, numRead);    } } 

4、使用StreamReader读取文件

用于在 Windows 8.x 应用商店应用中以 Stream 的形式打开文件的代码隐藏文件和 XAML 文件,并且通过使用 StreamReader 类的实例来读取其内容。 它使用异步方法以流的形式打开文件并读取其内容。

using System;using System.IO;using System.Text;using Windows.Storage.Pickers;using Windows.Storage;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;namespace ExampleApplication{    public sealed partial class BlankPage : Page    {        public BlankPage()        {            this.InitializeComponent();        }        private async void Button_Click_1(object sender, RoutedEventArgs e)        {            StringBuilder contents = new StringBuilder();            string nextLine;            int lineCounter = 1;            var openPicker = new FileOpenPicker();            openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;            openPicker.FileTypeFilter.Add(".txt");            StorageFile selectedFile = await openPicker.PickSingleFileAsync();            using (StreamReader reader = new StreamReader(await selectedFile.OpenStreamForReadAsync()))            {                while ((nextLine = await reader.ReadLineAsync()) != null)                {                    contents.AppendFormat("{0}. ", lineCounter);                    contents.Append(nextLine);                    contents.AppendLine();                    lineCounter++;                    if (lineCounter > 3)                    {                        contents.AppendLine("Only first 3 lines shown.");                        break;                    }                }            }            DisplayContentsBlock.Text = contents.ToString();        }    }}

XAML文件:

                                

相关文档:https://docs.microsoft.com/en-us/dotnet/standard/io/asynchronous-file-i-o