pbewithmd5anddes算法 对应.net_.NET 复习笔记 / 流

7767c1b5943eab62393e1ca8697b51f0.png
  • 一、什么是流?
  • 二、为什么要使用流?
  • 三、.NET 流基础
  • 四、.NET 中有哪些流?
  • 五、基础流 Stream 的读写操作
  • 六、读写操作辅助类型
  • 七、结语

一、什么是流?

“流”是字节序列的抽象,它可以是文件,进程间的通信管道以及 TCP/IP 套接字等等。总的来说你可以将其理解为:可进行读,写操作的任何内容。

二、为什么要使用流?

“流”的最大意义在于它统一了“数据源”读取,写入的“接口”。“数据源”可能会存在各种各样的特点,比如网络流可能存在延时或超时等。程序在使用“数据源”的时也可能会有不同的场景,比如影音数据并不需要在全部载入后才开始处理。“流”的设计就可以满足以上描述的各种场景的数据读写。

三、.NET 流基础

Stream Class (System.IO)​docs.microsoft.com
32971af70577cbdfb120d0ce65bdfc2e.png

抽象类 System.IO.Stream 是 .NET 中所有“流”的基类。它定义了流最基本的功能,涉及三个基本操作:读,写,查找。下面是 Stream 类中定义的用于支持这些操作的主要属性和方法,这些属性和方法都需要在具体的派生类中实现。

  • CanRead,指示流是否可读。
  • CanWrite,指示流是否可写,每次写入指定的内容并更新当前的位置。
  • CanSeek,指示流是否支持查找。
  • CanTimeout,指示流是否会超时。
  • Length,流的长度。
  • Position,当前读取的位置。
  • Read,读取方法,读取的最小单位为一个字节/Byte,既8位二进制数据。
  • Write,写入方法,写入的最小单位为一个字节/Byte,既8位二进制数据。

更多的关于 Stream 类的内容可以查看下面的源代码。

Stream类源代码​github.com

四、.NET 中有哪些流?

为了让你能方便的使用流, .NET 在“标准库”(BCL)中提供了对应下面这些数据源的流类型:

1. 文件

FileStream,基于文件的带缓冲的流。

2. 压缩文件

BrotliStream,为 Brotli 数据格式的文件提供压缩和解压缩流。

DeflateStream,提供使用 Deflate 算法的压缩与解压缩流。

GZipStream,为 GZip 数据格式提供压缩与解压缩流。

3. 命名管道

PipeStream,为匿名和命名管道提供流对象。

4. 网络

NetworkStream,基于套接字的不带缓冲的流。

5. 数据库

SqlFileStream,为 SQL Server 中 FILESTREAM 字段提供的流对象。

OracleBFile,为 Oracle 中的 BFILE 类型提供流对象。

OracleLob,为 Oracle 中的大型对象二进制数据(LOB)提供流对象。

6. 内存

MemoryStream,一个对应数据源为托管内存空间的流。

UnmanagedMemoryStream,非托管内存空间的流,该类型提供了在托管代码中访问非托管内存空间的能力。

7. 打印

PrintQueueStream,表示在打印队列中进行后台处理的打印作业的流。

8. 加密

CryptoStream,可以指定算法的加解密流。

9. COM

COMCharStream,表示一个将其数据发送给 IMessageReceiver 的流。

10. 缓冲

BufferedStream,一个包装类型,用于为那些没有缓冲的流添加缓冲能力。

这些流类型基本覆盖了我们 IO 操作的常用场景,下面我们来了解“流”的基本操作:读和写。

五、基础流 Stream 的读写操作

Stream的读写代码,

using System;
using System.IO;
using System.Text;

namespace DemoCode
{
    class Program
    {
        static void Main(string[] args)
        {
            //实例化流
            Stream s = new MemoryStream();
            //写入流, 48 为 ASCII 码中 0 的十进制编码
            for (int i = 48; i < 122; i++)
            {
                s.WriteByte((byte)i);
            }


            //重置流当前位置用于读取
            s.Position = 0;
            // bytes为用于保存读取数据的字节数组
            byte[] bytes = new byte[s.Length];
            //读取流内容
            while (s.Read(bytes, 0, (int)bytes.Length) > 0)
            {
                continue;
            }

            //以ASCII码输出读取的内容
            Console.WriteLine(ASCIIEncoding.ASCII.GetString(bytes));
        }
    }
}

上面代码输出为

4aaa9285f116787b18bf20ea54ed46f1.png

对应特定数据源的 Stream 派生类型会提供更多的方法,使用起来更方便。下面是 FileStream 的演示代码。

由于在实际场景中流对应的数据源通常是非托管 IO,推荐使用using语句以确保非托管资源在流使用后得到妥善的释放。

using System;
using System.IO;
using System.Text;

class Test
{
    public static void Main()
    {
        string path = @"c:tempMyTest.txt";

        //创建用于写入文件流的文件并返回对应的文件流实例
        using (FileStream fs = File.Create(path))
        {
            //将字符串以UTF8编码转换为字节数组
            byte[] info = new UTF8Encoding(true).GetBytes("test string");
            fs.Write(info, 0, info.Length);
        }

        //打开写入后的文件并获得对应的文件流
        using (FileStream fs = File.OpenRead(path))
        {
            byte[] bs = new byte[1024];
            UTF8Encoding temp = new UTF8Encoding(true);
            //将文件流内容读取到bs字节数组
            while (fs.Read(bs,0,bs.Length) > 0)
            {
                Console.WriteLine(temp.GetString(bs));
            }
        }
    }
}

六、读写操作辅助类型

上面 FileStream 示例中的读写操作的内容均是字节数组,导致我们需要在字节数组与字符串之间进行编码和解码,这样不够“生产力”。所以 .NET 提供了 Reader 和 Writer 类型来帮助我们快速的进行读写操作。

下图是 System.IO 命名空间下的 Reader 和 Writer 类型及它们之间的关系,

a5a69b4a05d47c8ebee579e64f98c01f.png

其中 TextReader/TextWriter 是抽象类型,这两个类型定义了字符串的基本读写操作。派生类 StreamReader 和 StreamWriter 的作用就是在流中读写字符串,如果我们把“流”比喻成装载数据的火车,那么 StreamReader 和 StreamWriter 就是装卸字符串数据的装卸机。

下面的代码演示这两个类型进行的字符串流的读写操作做,

using System;
using System.IO;

namespace DemoCode
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = @"c:tempMyTest.txt";
            if (!File.Exists(path))
            {
                File.Create(path);
            }
            //写入字符串到流
            using (Stream fs = File.OpenWrite(path))
            {
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine("text write by StreamWriter");
                sw.Flush();
            }

            //从流中读取字符串
            using (Stream fs = File.OpenRead(path))
            {
                StreamReader sr = new StreamReader(fs);

                var txt = sr.ReadToEnd();
                Console.WriteLine(txt);

            }
        }
    }
}

是不是相比之前简便了很多!

不过除此之外,如果只是相对简单的读写操作,还有更简便的方法就是使用System.IO.File 类型,它提供了一系列常用的文件操作和读写方法。不过本篇是讨论流的所以这里就不展开了,感兴趣的朋友可以查看下面的链接。

https://docs.microsoft.com/zh-cn/dotnet/api/system.io.file?view=netcore-3.1​docs.microsoft.com

七、结语

除了文件流 FileStream 之外,包括网络流 NetworkStream 以及 压缩/解压缩流也是实际编程中常用到的流,关于它们的更多内容可以参考下面的链接。

NetworkStream Class (System.Net.Sockets)​docs.microsoft.com
32971af70577cbdfb120d0ce65bdfc2e.png
System.IO.Compression Namespace​docs.microsoft.com
32971af70577cbdfb120d0ce65bdfc2e.png

本文简单的罗列了一些关于流的知识点,希望能对你认识 .NET 中的流有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值