概述
流,stream,总是记不住,每次使用的时候都要去搜索,并且心里还没有底,到底该怎么组合使用,也是比较混乱的,主要还是没有理清楚这么多流之间的关系以及功能分配。
这里梳理下基本的常用的流。
一个一个看,理清楚他们之间的区别于关系
File直接操作文件
其中类Stream为抽象类。
MemoryStream:对内存进行读取与写入,对标FileStream
BufferedStream:对缓冲器进行读取/写入 ,装饰Stream,增加缓冲
FileStream:对文件执行读取与写入
TextReader/TextWriter为抽象类。
StreamReader/StreamWirter 以string形式读取和写入流,装饰Stream
StringReader/StringWriter 以StringBuilder为载体,操作string
NetworkStream 网络流,网络通信使用
Demo代码:
static void Main(string[] args)
{
//StreamReader();
//StringReader();
//StringWriter();
//StreamWriter();
//MemoryStream();
//BufferdStream();
NetworkStream();
Console.ReadLine();
//StringReader
}
private static void NetworkStream()
{
int PORT_NO = 5000;
string SERVER_IP = "127.0.0.1";
//NetworkStream ns = new NetworkStream();
IPAddress localAdd = IPAddress.Parse(SERVER_IP);
TcpListener listener = new TcpListener(localAdd, PORT_NO);
Console.WriteLine("server Listening...");
listener.Start();
//进来的客户端连接
Thread thread = new Thread(() => {
Thread.Sleep(2000);
//字符串发送到服务器
string textToSend = $"{DateTime.Now.ToString()}:hello,server.";
//在IP和端口上,建立一个TCPClient对象
TcpClient client = new TcpClient(SERVER_IP, PORT_NO);
client.ReceiveBufferSize = 1024 * 1024 * 20;
NetworkStream nwStream1 = client.GetStream();
byte[] bytesToSend = Encoding.UTF8.GetBytes(textToSend);
//发送文本
Console.WriteLine("client Sending : " + textToSend);
nwStream1.Write(bytesToSend, 0, bytesToSend.Length);
nwStream1.Flush();
//读回文本
byte[] bytesToRead = new byte[client.ReceiveBufferSize];
int bytesRead1 = nwStream1.Read(bytesToRead, 0, client.ReceiveBufferSize);
using (FileStream fs1 = new FileStream("./image_receive.png", FileMode.Create))
{
fs1.Write(bytesToRead, 0, bytesRead1);
}
Console.ReadLine();
client.Close();
});
thread.Start();
TcpClient servers = listener.AcceptTcpClient();
//通过流获取进来的数据
NetworkStream nwStream = servers.GetStream();
byte[] buffer = new byte[servers.ReceiveBufferSize];
//读取进来的流
int bytesRead = nwStream.Read(buffer, 0, servers.ReceiveBufferSize);
//接收的数据转换成字符串
string dataReceived = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine("server Received :" + dataReceived);
//给客户端写回
Console.WriteLine("server Sending back a picture... ");
byte[] imgContent;
using (FileStream fs = new FileStream("./image.png", FileMode.Open))
{
imgContent = new byte[fs.Length];
fs.Read(imgContent, 0, (int)fs.Length);
}
nwStream.Write(imgContent, 0, imgContent.Length);
servers.Close();
listener.Stop();
Console.ReadLine();
}
private static void BufferdStream()
{
//增加buffer功能,不用每次写入都访问磁盘
using (FileStream fs = new FileStream("./tt.dat", FileMode.OpenOrCreate))
using (BufferedStream bf = new BufferedStream(fs))
using (StreamWriter sw = new System.IO.StreamWriter(bf))
{
sw.Write("111111111111111");
sw.WriteLine("222222222222222222");
int n= 0;
while (n < 10000000)
{
sw.WriteLine("333333333333");
n++;
}
}
}
private static void MemoryStream()
{
Image image = new Bitmap(@"./hello.bmp");
using(MemoryStream ms = new MemoryStream()) //内存流视为内存存储 -- 对应FileStream 一文件为存储
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
using (FileStream fs = new FileStream("./my.bmp", FileMode.OpenOrCreate))
{
fs.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
}
}
}
private static void StreamWriter()
{
if (File.Exists("./test2.dat"))
File.Delete("./test2.dat");
FileStream fs = new FileStream("./test2.dat", FileMode.OpenOrCreate);
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("hello\r\nworld.");
}
fs.Close();
if (File.Exists("./test3.dat"))
File.Delete("./test3.dat");
File.Create("./test3.dat").Close();
using (StreamWriter sw1 = new System.IO.StreamWriter("./test3.dat"))
{
sw1.Write("sjfosjffffffffff");
}
}
private static void StringWriter()
{
using (StringWriter tw = new StringWriter(new StringBuilder()))
{
tw.WriteLine("ssss\0123131313\r\n服务范围分为");
var sb = tw.GetStringBuilder();
Console.WriteLine(sb.ToString());
}
}
private static void StreamReader()
{
Stopwatch st = new Stopwatch();
st.Start();
string str = File.ReadAllText("./test.dat", Encoding.UTF8);
Console.WriteLine("time 1:" + st.ElapsedMilliseconds.ToString());
st.Restart();
StreamReader sr = new StreamReader("./test.dat", Encoding.UTF8);
int n = 0;
while (n < 20)
{
string line = sr.ReadLine();
Console.WriteLine(line);
n++;
}
Console.WriteLine("time 2:" + st.ElapsedMilliseconds.ToString());
sr.Close();
st.Restart();
sr = new StreamReader("./test.dat", Encoding.UTF8);
n = 0;
char[] chs = new char[10];
sr.BaseStream.Seek(60000000, SeekOrigin.Begin);
sr.ReadBlock(chs, 0, 10);
Console.WriteLine(chs);
Console.WriteLine("time 3:" + st.ElapsedMilliseconds.ToString());
}
private static void StringReader()
{
string text = "jiewfjo减肥IE我就服务\r\n是\0否为1231313";
Console.WriteLine(text);
using (TextReader r1 = new StringReader(text))
{
Console.WriteLine(r1.ReadLine());
}
using (TextReader reader = new StringReader(text))
{
while (reader.Peek() != -1)
{
Console.WriteLine("Peek = {0}", (char)reader.Peek());
Console.WriteLine("Read = {0}", (char)reader.Read());
}
}
}
总结:
File -> Stream -> TextStream -> StringReader/StringWriter -> FileStream -> StreamReader/StreamWriter -> BufferdStream -> MemoryStream -> NetworkStream
按照这个路径去梳理一遍,基本就能理好看似混乱的关系。