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