(一)流的概述
流代表源与目标之间传输的一定的数据量。无论是文件、网络还是打印机等设备,流都要提供一种通用的方式与数据进行交互。流不仅可以访问文件,还可以访问网络、内存地址等。
可以看到,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);
}