C# 流
流,是输入/输出操作中表示数据内容的字节按照顺序进行排列。
内存流,即从内存中划分出一个特定区域,程序可将字节序列存放到该区域中。内存流很适合读写临时数据,因为不用处理磁盘上的文件,可以在内存中完成处理,速度快,用完就释放。对于不需要长久保留的特别适合。
向内存流写入内容
MemoryStream
类封装了一系列操作内存流的方法。所有相关类型都实现了IDisposable
接口,以便用完后释放资源。
// 要写入内存流的字节数组 byte[] buffer = { 155, 16, 3, 200, 77, 9, 21, 34, 60 }; // 创建内存流实例 using(MemoryStream stream = new MemoryStream()) { // 写入内容 stream.Write(buffer); }
将内存流中的内容转化为字节数组
// 字节数组 byte[] data = null; // 在内存流中写入随机字节 using (MemoryStream stream = new MemoryStream()) { // 用于产生随机字节 Random rand = new Random(); // 写入 20 个字节 byte[] buffer = new byte[20]; rand.NextBytes(buffer); stream.Write(buffer); // 从流中重新提取字节数组 data = stream.ToArray(); } // 输出字节数组 Console.WriteLine("从内存流中获取的字节数组:"); Console.WriteLine(BitConverter.ToString(data));
从内存流中读取内容
本例使用int Read(byte[] buffer, int offset, int count);
-
buffer
参数是一个字节数组,用来存放读出来的字节。 -
offset
参数指定数组中开始存入读出字节的位置索引。 -
count
参数指定要从流中读入的字节的最大数量。 - 返回值表示实际读取的字节数量。
static void Main(string[] args) { using(MemoryStream stream = GetStream()) { byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); Console.WriteLine($"读出的字节:\n{BitConverter.ToString(buffer)}"); } Console.Read(); } static MemoryStream GetStream() { MemoryStream ms = new MemoryStream(); // 写入 5 个字节 ms.WriteByte(1); ms.WriteByte(2); ms.WriteByte(3); ms.WriteByte(4); ms.WriteByte(5); // 将读定指针复位 ms.Position = 0L; return ms; }
使用StreamWriter类将文本写入文件
StreamWriter
类继承了TextWriter
类,专门写入文本内容,虽然允许其他类型,但最终都以文本形式写入。默认UTF-8编码,也可以用StreamWriter(System.IO.Stream, System.Text.Encoding );
using (StreamWriter writer = new StreamWriter("abc.txt")) { writer.WriteLine(300); writer.Write(0.335M); writer.Write("test"); writer.WriteLine(false); writer.Write(DateTime.Today); }
使用StreamReader类读取文本文件
static void Main(string[] args) { WriteSomethingToFile(); using(StreamReader reader = new StreamReader("demo.txt")) { string line = null; while((line = reader.ReadLine()) != null) { Console.WriteLine(line); } } Console.Read(); } static void WriteSomethingToFile() { using(StreamWriter writer = new StreamWriter("demo.txt")) { writer.WriteLine("first line"); writer.WriteLine(5000000L); writer.WriteLine(0.000075d); writer.WriteLine(6600); } }
调用Seek方法重新设置流的当前位置
读写流中内容有时需要修改流的当前位置。Seek
方法可以做到。
Seek方法有两个参数:
第一个参数是新的位置,如果是正值则流向结尾移动,反之向开头移动。
第二个参数是指定新位置的参考点,有SeekOrigin
枚举指定。有三个枚举值:
Begin:新位置以流的开头为参考;
Current:新位置以流当前位置为参考;
End:新位置以流的结尾设定。
using (MemoryStream ms = new MemoryStream()) { Console.Write("写入流的字节:\n"); for (byte x = 1; x <= 8; x++) { ms.WriteByte(x); Console.Write(" 0x{0:x2}", x); } Console.WriteLine("\n"); // 改变流的当前位置 ms.Seek(-3, SeekOrigin.End); Console.WriteLine("最后 3 个字节为:"); int r; while ((r = ms.ReadByte()) > -1) { Console.Write(" 0x{0:x2}", r); } } Console.Read();
结果:
写入流的字节: 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 最后 3 个字节为: 0x06 0x07 0x08
通过Position属性更改流的当前位置
要设置流的当前位置,除了Seek外,可以直接设置Position属性。该属性值从0开始计算。
using(FileStream fs = new FileStream("demo", FileMode.OpenOrCreate)) { Random rand = new Random(); byte[] data = new byte[10]; rand.NextBytes(data); fs.Write(data); } // 读取文件,从第 6 个字节开始读 using(FileStream fs = new FileStream("demo", FileMode.Open)) { // 重新设定当前位置 fs.Position = 5L; byte[] buffer = new byte[fs.Length - fs.Position]; // 读入字节 fs.Read(buffer, 0, buffer.Length); // 输出结果 Console.WriteLine($"文件中的最后 5 个字节为:\n{BitConverter.ToString(buffer)}"); } Console.Read();
结果:
文件中的最后 5 个字节为: 28-D3-88-45-E5
本文来自博客园,作者:一纸年华,转载请注明原文链接:https://www.cnblogs.com/nullcodeworld/p/18210637
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)