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();
}
else
inputS.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的基本介绍以及使用!