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
posted @   一纸年华  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航

向内存流写入内容
将内存流中的内容转化为字节数组
从内存流中读取内容
使用StreamWriter类将文本写入文件
使用StreamReader类读取文本文件
调用Seek方法重新设置流的当前位置
通过Position属性更改流的当前位置