FileStream的使用
一.基本介绍:
二.FileStream读写文件实例:
string path1 = @"d\test\test1.txt";string path2= @"d\test\test2.txt";byte[] buffered = new byte[1024];using (FileStream fsr = new FileStream(path1, FileMode.Open, FileAccess.Read)) {using (FileStream fsw = new FileStream(path1, FileMode.OpenOrCreate, FileAccess.Write)) {int count = fsr.Read(buffered, 0, buffered.Length);while (true) {if (count == 0) break;fsw.Write(buffered, 0, buffered.Length);}}}
三.FileStream异步复制文件:
第一种方式: 不建议,复杂
private static FileStream inputS = null;private static FileStream OutputS = null;private static int bufferSize = 1024;private static byte[] buffered = new byte[1024];static void Main(string[] args){string path = @"d:\test1\test.txt";Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}");ReadAsync01(path);}public static void ReadAsync01(string path) {Console.WriteLine($"异步读取:{Thread.CurrentThread.ManagedThreadId}");inputS = new FileStream(path, FileMode.Open, FileAccess.Read,FileShare.Read,buffered.Length,true);inputS.BeginRead(buffered, 0, buffered.Length, OnCompleteRead, null);}//异步回调的方法private static void OnCompleteRead(IAsyncResult asyncResult) {Console.WriteLine($"异步回调{Thread.CurrentThread.ManagedThreadId}");//读取的字节数据int count =inputS.EndRead(asyncResult);string writePath = @"d:\test2\test2.txt";if (count > 0) {if (count < bufferSize){WriteAsync01(writePath, count);inputS.Close();}elseinputS.BeginRead(buffered, 0, buffered.Length, OnCompleteRead, null);}}public static void WriteAsync01(string path,int len){Console.WriteLine($"异步写入:{Thread.CurrentThread.ManagedThreadId}");byte[] buffered = new byte[1024];OutputS = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.None, buffered.Length, true);OutputS.BeginWrite(buffered, 0, buffered.Length, OnCompleteRead, null);OutputS.Close();}//异步回调的方法private static void OnCompleteQWrite(IAsyncResult asyncResult){Console.WriteLine($"异步回调{Thread.CurrentThread.ManagedThreadId}");inputS.EndWrite(asyncResult);}}
第二种方式:
private string pathr = @"d:\test1\test1.txt"; private string pathw = @"d:\test2\test2.txt"; private int bufferSize= 1024; public async void read() {Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}");await ReadFileAsync();Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}");}public async Task ReadFileAsync() {Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}");byte[] buffered = new byte[bufferSize];using (FileStream fis = new FileStream(pathr, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, true)) {using (FileStream fws = new FileStream(pathw, FileMode.Open, FileAccess.Write, FileShare.None, bufferSize, true)) {int count = 0;count= await fis.ReadAsync(buffered, 0, buffered.Length);while (count != 0) {await fws.WriteAsync(buffered, 0, count);count = await fis.ReadAsync(buffered, 0, buffered.Length);}}}}
四.MemoryStream的使用:
①.基本介绍:
②主要的构造函数:
//// 摘要:// 使用初始化为零的可扩展容量初始化 System.IO.MemoryStream 类的新实例。public MemoryStream();//// 摘要:// 使用按指定要求初始化的可扩展容量初始化 System.IO.MemoryStream 类的新实例。//// 参数:// capacity:// 内部数组的初始大小(以字节为单位)。//// 异常:// T:System.ArgumentOutOfRangeException:// capacity 为负数。public MemoryStream(int capacity);//// 摘要:// 基于指定的字节数组初始化 System.IO.MemoryStream 类的无法调整大小的新实例。//// 参数:// buffer:// 从中创建当前流的无符号字节数组。//// 异常:// T:System.ArgumentNullException:// buffer 为 null。public MemoryStream(byte[] buffer);//// 摘要:// 在 System.IO.MemoryStream.CanWrite 属性按指定设置的状态下,基于指定的字节数组初始化 System.IO.MemoryStream// 类的无法调整大小的新实例。//// 参数:// buffer:// 从中创建此流的无符号字节的数组。//// writable:// System.IO.MemoryStream.CanWrite 属性的设置,确定该流是否支持写入。//// 异常:// T:System.ArgumentNullException:// buffer 为 null。public MemoryStream(byte[] buffer, bool writable);//// 摘要:// 基于字节数组的指定区域(索引)初始化 System.IO.MemoryStream 类的无法调整大小的新实例。//// 参数:// buffer:// 从中创建此流的无符号字节的数组。//// index:// buffer 内的索引,流从此处开始。//// count:// 流的长度(以字节为单位)。//// 异常:// T:System.ArgumentNullException:// buffer 为 null。//// T:System.ArgumentOutOfRangeException:// index 或 count 也不可小于零。//// T:System.ArgumentException:// 缓冲区长度减去 index 小于 count。public MemoryStream(byte[] buffer, int index, int count);//// 摘要:// 在 System.IO.MemoryStream.CanWrite 属性按指定设置的状态下,基于字节数组的指定区域,初始化 System.IO.MemoryStream// 类的无法调整大小的新实例。//// 参数:// buffer:// 从中创建此流的无符号字节的数组。//// index:// buffer 内的索引,流从此处开始。//// count:// 流的长度(以字节为单位)。//// writable:// System.IO.MemoryStream.CanWrite 属性的设置,确定该流是否支持写入。//// 异常:// T:System.ArgumentNullException:// buffer 为 null。//// T:System.ArgumentOutOfRangeException:// index 或 count 为负。//// T:System.ArgumentException:// 缓冲区长度减去 index 小于 count。public MemoryStream(byte[] buffer, int index, int count, bool writable);//// 摘要:// 在 System.IO.MemoryStream.CanWrite 属性和调用 System.IO.MemoryStream.GetBuffer 的能力按指定设置的状态下,基于字节数组的指定区域初始化// System.IO.MemoryStream 类的新实例。//// 参数:// buffer:// 从中创建此流的无符号字节的数组。//// index:// buffer 内的索引,流从此处开始。//// count:// 流的长度(以字节为单位)。//// writable:// System.IO.MemoryStream.CanWrite 属性的设置,确定该流是否支持写入。//// publiclyVisible:// 设置为 true 可以启用 System.IO.MemoryStream.GetBuffer,它返回无符号字节数组,流从该数组创建;否则为 false。//// 异常:// T:System.ArgumentNullException:// buffer 为 null。//// T:System.ArgumentOutOfRangeException:// index 或 count 为负数。//// T:System.ArgumentException:// 缓冲区长度减去 index 小于 count。public MemoryStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible);
③.基本使用
public void MemoryStreamEx() {MemoryStream memoryStream0 = new MemoryStream();MemoryStream memoryStream1 = new MemoryStream(1024);byte[] buffered = new byte[1024 * 1024];MemoryStream memoryStream2 = new MemoryStream(buffered);//操作memoryStream0.Read(buffered, 0, buffered.Length);memoryStream1.Write(buffered, 0, buffered.Length);//SeekOrigin.Begin//SeekOrigin.Current;//SeekOrigin.End;memoryStream2.Seek(2, SeekOrigin.Begin); //指定流的开始位置 设置新的位置using (FileStream fws = new FileStream(pathw, FileMode.Open, FileAccess.Write, FileShare.None, buffered.Length)) {memoryStream0.WriteTo(fws); //将缓冲区中的数据写入到文件中 持久化的过程}}
总结:
今天我们主要介绍的是关于文件流FileStream的读写操作以及基于内存的MemoryStream,并通过以上这两种方式我们都实现了对于文件的异步复制,但是我们可以明显看出第二种方式的优势:简单明了并且易于理解且性能优于第一种,下次我们将会带来BufferedStream的基本介绍以及使用!