(一)流的概述
流代表源与目标之间传输的一定的数据量。无论是文件、网络还是打印机等设备,流都要提供一种通用的方式与数据进行交互。流不仅可以访问文件,还可以访问网络、内存地址等。
可以看到,FileStream和MemoryStream都是直接继承于Stream抽象类。流继承于 System.IO.Stream抽象类,Stream的常用成员包括:
CanRead/CanWrite/CanSeek
Close()
Flush()
FlushAsync()
Length
Position
CopyTo(Stream)
CopyTo(Stream,Int32)
CopyToAsync(Stream,Int32)
CopyToAsync(Stream,Int32,CancellationToken)
Read(byte[],int,int)
ReadAsync(byte[],int,int,CancellationToken)
ReadAsync(byte[],int,int)
ReadByte()
Synchronized(Stream)在指定的Stream对象周围创建线程安全(同步)包装
Seek(Int64,SeekOrigin)
SetLength(Int64)
Write(byte[],int,int)
WriteAsync(byte[],int,int)
WriteAsync(Byte[],int,int,CancellationToken)
WriteByte(Byte)
(二)常用的流实现类
2.1 FileStream
System.IO.FileStream直接从Stream派生而来。可以使用File.Create(fileFullPath),File.OpenRead(path),File.Open(path,FileMode),
File.OpenWrite(string path[,System.IO.FileMode mode]),File.OpenWrite(path)等方法来获得FileStream对象。
官方文档中的例子:
using (FileStream fs = File.Create(path)) { AddText(fs, "This is some text"); AddText(fs, "This is some more text,"); AddText(fs, "\r\nand this is on a new line"); AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n"); for (int i=1;i < 120;i++) { AddText(fs, Convert.ToChar(i).ToString()); } } using (FileStream fs = File.OpenRead(path)) { byte[] b = new byte[1024]; UTF8Encoding temp = new UTF8Encoding(true); while (fs.Read(b,0,b.Length) > 0) { Console.WriteLine(temp.GetString(b)); } } private static void AddText(FileStream fs, string value) { byte[] info = new UTF8Encoding(true).GetBytes(value); fs.Write(info, 0, info.Length); } private async void Button_Click(object sender, RoutedEventArgs e) { UnicodeEncoding uniencoding = new UnicodeEncoding(); string filename = @"c:\Users\exampleuser\Documents\userinputlog.txt"; byte[] result = uniencoding.GetBytes(UserInput.Text); using (FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate)) { SourceStream.Seek(0, SeekOrigin.End); //using中调用异步方法,使用await挂起调用线程指导任务完成 await SourceStream.WriteAsync(result, 0, result.Length); } }2.2 MemoryStream
继承关系Object->MarshalByRefObject->Stream->MemoryStream
构造方法如下:即可以通过给定初始字节数组或初始容量来构造MemoryStream实例。
官方给出的使用案例如下:
static void Main() { int count; byte[] byteArray; char[] charArray; UnicodeEncoding uniEncoding = new UnicodeEncoding(); // Create the data to write to the stream. byte[] firstString = uniEncoding.GetBytes( "Invalid file path characters are: "); byte[] secondString = uniEncoding.GetBytes( Path.GetInvalidPathChars()); using(MemoryStream memStream = new MemoryStream(100)) { // Write the first string to the stream. memStream.Write(firstString, 0 , firstString.Length); // Write the second string to the stream, byte by byte. count = 0; while(count < secondString.Length) { memStream.WriteByte(secondString[count++]); } // Write the stream properties to the console. Console.WriteLine( "Capacity = {0}, Length = {1}, Position = {2}\n", memStream.Capacity.ToString(), memStream.Length.ToString(), memStream.Position.ToString()); // Set the position to the beginning of the stream. memStream.Seek(0, SeekOrigin.Begin); // Read the first 20 bytes from the stream. byteArray = new byte[memStream.Length]; count = memStream.Read(byteArray, 0, 20); // Read the remaining bytes, byte by byte. while(count < memStream.Length) { byteArray[count++] = Convert.ToByte(memStream.ReadByte()); } // Decode the byte array into a char array // and write it to the console. charArray = new char[uniEncoding.GetCharCount( byteArray, 0, count)]; uniEncoding.GetDecoder().GetChars( byteArray, 0, count, charArray, 0); Console.WriteLine(charArray); } }2.3 NetworkStream
官方文档中的例子
// Examples for constructors that do not specify file permission. // Create the NetworkStream for communicating with the remote host. NetworkStream myNetworkStream; if (networkStreamOwnsSocket){ myNetworkStream = new NetworkStream(mySocket, true); } else{ myNetworkStream = new NetworkStream(mySocket); }