一、 Stream类概述
在.NET Framework中,文件和流之间是有区别的。
文件是存储在磁盘上的数据集,它具有名称和相应的路径。当您打开文件并对其进行读写时,该文件称为流。
但是,流式传输不仅指打开的磁盘文件,还指网络数据。 .Net Framework允许在内存中创建流。另外,在控制台应用程序中,键盘输入和文本显示都是流。
1.流类
流类是所有流的抽象基类。
Stream类的主要属性是CanRead,CanWrite(是否支持读写),CanSeek(是否支持搜索),CanTimeout(是否可以超时),Length(流的长度),Position (获取或设置当前流的位置),ReadTimeout / WriteTimeout(获取或设置读写操作的超时时间)
Stream类的主要方法是BeginRead / EndRead(开始和结束异步读取操作),BeginWrite / EndWrite(开始和结束异步写入操作),Read(读取字节序列),ReadByte(读取一个字节),Seek (设置搜索位置),写入(写入字节序列),写入字节(写入一个字节),刷新(清除流的所有缓冲区并将缓冲的数据写入基本设备),关闭(关闭当前流)。
2. FileStream,MemoryStream,BufferedStream和NetworkStream FileStream FileStream:以流的形式读取,写入,打开和关闭文件。此外,它还可用于处理其他与文件相关的操作系统句柄,例如管道,标准输入/输出等。内存流MemoryStream类:用于在内存中创建流以临时保留数据,因此无需在硬盘上创建临时文件。它将数据封装为无符号字节序列,可以直接读取,写入和搜索。 BufferedStream BufferedStream类:意味着先将流添加到缓冲区,然后再读取/写入数据。缓冲区是一个字节块,用于在存储区域中缓冲数据。使用缓冲区可以减少访问数据时对操作系统的调用次数,并增强系统的读/写功能。网络流NetworkStream类:提供用于网络访问的基本数据流。
请注意,FileStream类还具有缓冲功能。创建FileStream类的实例时,只需指定缓冲区的大小即可。
二、 FileStream FileStream

文件流类FileStream公开了基于文件的Stream,该流同时支持同步读/写操作和异步读/写操作。
FileStream类的特征是操纵字节和字节数组。此方法不适用于操作由字符数据组成的文本文件,并且适合处理非文本文件。
FileStream类提供了对文件的低级和复杂操作,因此可以实现更高级的功能。
1、读取文件
Read,ReadByte()
//创建d:\file.txt的FileStream对象 FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate); byte[] bData = new byte[fstream.Length]; //设置流当前位置为文件开始位置 fstream.Seek(0, SeekOrigin.Begin); //将文件的内容存到字节数组中(缓存) fstream.Read(bData, 0, bData.Length); string result = Encoding.UTF8.GetString(bData); Console.WriteLine(result); if (fstream != null) { //清除此流的缓冲区,使得所有缓冲的数据都写入到文件中 fstream.Flush(); fstream.Close(); }
除了将字节数组转换为用于显示的字符串外,还可以使用字节数组
//1、显示成图片 MemoryStream mstream = new MemoryStream(bData); Image img = Image.FromStream(mstream);
//2、作为值存储到 SqlCommand comm = new SqlCommand(); comm.Parameters.Add("images", SqlDbType.Image).Value = bData;
//3、写入文件 File.WriteAllBytes("c:\aa.txt", bData); FileStream fstream = new FileStream("c:\aa.txt"); fstream.Write(bData, 0, bData.Length);
2、逐块读取文件

int bufferSize = 5; //创建d:\file.txt的FileStream对象 FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, bufferSize, false);//false表示同步读 byte[] bData = new byte[bufferSize]; //设置流当前位置为文件开始位置 fstream.Seek(0, SeekOrigin.Begin); int bytesRead; do { //将文件的内容存到字节数组中(缓存) bytesRead = fstream.Read(bData, 0, bData.Length); string result = Encoding.UTF8.GetString(bData, 0, bytesRead); Console.WriteLine(result); } while (bytesRead > 0); if (fstream != null) { //清除此流的缓冲区,使得所有缓冲的数据都写入到文件中 fstream.Flush(); fstream.Close(); }
3、异步读取文件
ManualResetEvent mEvent = new ManualResetEvent(false); int bufferSize = 5; byte[] bData = new byte[bufferSize]; FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, bufferSize, true);//false表示异步读 AsyncCallback callback = null;
callback = (IAsyncResult ar) =>
{ int bytesRead = fstream.EndRead(ar); Console.WriteLine(Encoding.UTF8.GetString(bData, 0, bytesRead)); if (bytesRead > 0) { fstream.BeginRead(bData, 0, bufferSize, callback, null);//继续读 } else { fstream.Close(); mEvent.Set();//读取完毕,发送信号 } }; IAsyncResult async = fstream.BeginRead(bData, 0, bufferSize, callback, null); mEvent.WaitOne(5000, false); Console.WriteLine("读取完成");
备注:IAsyncResult接口的成员
AsyncState获取一个用户定义的对象,该对象限制或包含有关异步操作的信息。
AsyncWaitHandle获取用于等待异步操作完成的WaitHandle。
CompletedSynchronously获取一个值,该值指示异步操作是否同步完成。
IsCompleted获取一个值,该值指示异步操作是否已完成。
4、写入文件
写,写字节(字节)

//创建d:\file.txt的FileStream对象 FileStream fstream = new FileStream(@"d:\file.txt", FileMode.OpenOrCreate); byte[] bData = Encoding.UTF8.GetBytes("test filestream"); //设置流当前位置为文件开始位置 fstream.Seek(0, SeekOrigin.Begin);
//将字节数组中的内容写入文件 fstream.Write(bData, 0, bData.Length); if (fstream != null) { //清除此流的缓冲区,使得所有缓冲的数据都写入到文件中 fstream.Flush(); fstream.Close(); }
三、 MemoryStream类
与字节数组相比,内存流具有流的独特特性,并且容量可以自动增长。
在数据加密和可变长度数据的缓存中,使用存储流更加方便。
下面的代码示例演示如何读写使用内存作为后备存储的数据。
int count; UnicodeEncoding uniEncoding = new UnicodeEncoding();
//创建要写入流的数据
byte[] firstString = uniEncoding.GetBytes("Invalid file path characters are: "); byte[] secondString = uniEncoding.GetBytes(Path.GetInvalidPathChars()); using (MemoryStream memStream = new MemoryStream(100)) { // 将第一个字符串写入流. memStream.Write(firstString, 0, firstString.Length); // 将第二个字符串按字节写入流. count = 0; while (count < secondString.Length) { memStream.WriteByte(secondString[count++]); } // 将流属性写入控制台. Console.WriteLine("Capacity = {0}, Length = {1}, Position = {2}\n", memStream.Capacity.ToString(), memStream.Length.ToString(), memStream.Position.ToString()); // 将位置设置为流的开始. memStream.Seek(0, SeekOrigin.Begin); // 从流中读取前20个字节. byte[] byteArray = new byte[memStream.Length]; count = memStream.Read(byteArray, 0, 20); // 一个字节一个字节地读取剩下的字节. while (count < memStream.Length) { byteArray[count++] = Convert.ToByte(memStream.ReadByte()); } // 将字节数组解码为char数组并将其写入控制台. char[] charArray = new char[uniEncoding.GetCharCount(byteArray, 0, count)]; uniEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0); Console.WriteLine(charArray); }
1、 ToArray()和GetBuffer()之间的区别:
//将流中的数据复制到一个byte[]中,速度比GetBuffer()稍慢,但不会将无用的空数据放入buffer中。 byte[] byteArray = memStream.ToArray(); //把流中的Buffer的引用传递出来,速度较快,Buffer的大小有流的Capacity决定的,但会传无用的空数据。 byte[] byteArray = memStream.GetBuffer();
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/dianqi/article-363455-1.html
说的透彻
允许同志结婚倒是不错的见解
还真的是