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 @ 2020-12-15 09:23  一纸年华  阅读(3)  评论(0编辑  收藏  举报  来源