C# 数据流(Data Streams)

简介

在C#中,数据流(Data Streams)是一种用于读取和写入数据的抽象概念。数据流通常用于处理文件、网络通信、内存中的数据等场景。C#提供了多种数据流类来支持不同类型的数据读写操作。

Stream(流)

在C#中,Stream 是一个抽象类,用于提供对数据的读取和写入操作。它定义了基本的读写方法和属性,但本身不能直接实例化,需要通过其子类来实现具体的数据流操作。Stream 类是数据流处理的核心,提供了一种统一的接口,使得可以以相似的方式处理各种不同来源和格式的数据。

FileStream(文件流)

FileStream 是C#中用于对文件进行读写操作的类,它派生自 Stream 类。通过 FileStream,可以直接操作文件的数据,包括读取文件内容、写入数据到文件以及控制文件的访问权限等。

原理

FileStream 通过将文件视为字节流的方式进行操作。它将文件的内容读取到内存中的缓冲区中,或者将内存中的数据写入到文件中。FileStream 类提供了多种构造函数,允许以不同的模式(如打开、创建、截断文件等)打开文件,并支持同步和异步操作。

案例

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // 写入数据到文件
        using (FileStream fs = new FileStream("example.txt", FileMode.Create))
        {
            string data = "Hello, FileStream!";
            byte[] byteData = System.Text.Encoding.UTF8.GetBytes(data);
            fs.Write(byteData, 0, byteData.Length);
        }

        // 从文件中读取数据
        using (FileStream fs = new FileStream("example.txt", FileMode.Open))
        {
            byte[] buffer = new byte[1024];
            int bytesRead = fs.Read(buffer, 0, buffer.Length);
            string text = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
            Console.WriteLine(text);
        }
    }
}

 应用场景

  • 文件读写操作FileStream 主要用于对文件进行读写操作,适用于需要直接访问文件内容的场景。
  • 文件处理任务:对于需要读取、修改或创建文件的任务,FileStream 提供了灵活且高效的方式来处理文件。

优点

  • 直接操作文件FileStream 允许直接操作文件的数据,而无需将文件内容加载到内存中。
  • 高效性:通过使用缓冲区和异步操作,可以提高文件读写的效率。
  • 灵活性FileStream 提供了多种构造函数和参数,可以满足不同的文件读写需求。

缺点

  • 操作复杂性:相比于高级别的文件操作接口,使用 FileStream 进行文件读写操作可能需要编写更多的代码。
  • 不适用于所有场景:某些情况下,如果只是简单的文件读写操作,可能会选择更高级别的文件操作接口(如:File.ReadAllTextFile.WriteAllText、StreamReaderStreamWriter)来实现,而不是直接使用 FileStream

MemoryStream(内存流)

简介

MemoryStream 是C#中用于在内存中进行数据读写操作的类,它派生自 Stream 类。通过 MemoryStream,可以将数据存储在内存中的缓冲区中,而无需依赖外部文件或网络资源。

原理

MemoryStream 通过将数据存储在内存中的字节数组中来实现数据的读写操作。它提供了对字节数组的读写方法,并支持对内存缓冲区进行扩展或截断。MemoryStream 类可以直接操作内存中的数据,不涉及文件或网络的读写操作,因此速度较快。

案例

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // 写入数据到内存流
        using (MemoryStream ms = new MemoryStream())
        {
            string data = "Hello, MemoryStream!";
            byte[] byteData = System.Text.Encoding.UTF8.GetBytes(data);
            ms.Write(byteData, 0, byteData.Length);

            // 将内存流的数据读取到字节数组中
            byte[] buffer = ms.ToArray();

            // 将字节数组转换为字符串并输出
            string text = System.Text.Encoding.UTF8.GetString(buffer);
            Console.WriteLine(text);
        }
    }
}

 应用场景

  • 数据处理:适用于需要在内存中临时存储和处理数据的场景,如数据转换、加密解密等操作。
  • 内存缓存:可用于实现内存缓存,临时存储需要频繁访问的数据,以提高程序的性能。
  • 测试和调试:在单元测试或调试过程中,可以使用 MemoryStream 来模拟文件流操作,而无需创建实际的文件。

优点

  • 速度快:由于数据存储在内存中,因此读写操作速度较快。
  • 灵活性MemoryStream 提供了对内存缓冲区的灵活操作,如扩展、截断等。
  • 无需外部资源:不依赖外部文件或网络资源,适用于临时数据的处理和存储。

缺点

  • 内存占用:由于数据存储在内存中,可能会占用大量的内存空间,特别是处理大量数据时。
  • 数据临时性:内存中的数据在程序结束后会被释放,因此不适合长期存储大量数据。

NetworkStream(网络流)

简介

NetworkStream 是C#中用于通过网络进行数据通信的类,它派生自 Stream 类。通过 NetworkStream,可以在网络套接字上进行数据的读写操作,实现客户端和服务器之间的数据交换。

原理

NetworkStream 通过底层的网络套接字(Socket)来进行数据传输。当创建 NetworkStream 对象时,需要将一个已连接的套接字作为参数传递给它。之后,可以使用 NetworkStream 对象的方法来进行数据的读写操作,这些操作将直接影响底层的套接字。

案例

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;

class Program
{
    static void Main()
    {
        // 客户端连接服务器
        TcpClient client = new TcpClient("127.0.0.1", 8888);

        // 获取客户端的网络流
        NetworkStream stream = client.GetStream();

        // 发送数据到服务器
        string message = "Hello, Server!";
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(message);
        stream.Write(buffer, 0, buffer.Length);

        // 从服务器接收数据
        buffer = new byte[1024];
        int bytesRead = stream.Read(buffer, 0, buffer.Length);
        string response = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead);
        Console.WriteLine("Server response: " + response);

        // 关闭流和连接
        stream.Close();
        client.Close();
    }
}

 应用场景

  • 网络通信:主要用于客户端和服务器之间的数据传输,如实现网络通信协议(如HTTP、FTP等)中的数据交换。
  • 远程控制:可用于实现远程控制功能,如远程命令执行、文件传输等。
  • 实时数据传输:适用于需要实时传输数据的场景,如在线游戏、实时监控系统等。

优点

  • 简单易用NetworkStream 提供了简单易用的接口,使得进行网络数据传输变得更加便捷。
  • 高效性:通过底层的套接字实现,可以实现高效的网络数据传输。
  • 灵活性:支持同步和异步操作,可以根据需要选择合适的操作方式。

缺点

  • 阻塞式操作:默认情况下,NetworkStream 的读写操作是阻塞的,可能会导致程序在等待数据到达时被阻塞。
  • 不稳定性:由于网络环境的不确定性,可能会出现网络连接中断、数据丢失等问题,需要进行适当的异常处理。

六、StreamReader 和 StreamWriter

简介

StreamReaderStreamWriter 是C#中用于在文件、流等数据源上进行文本数据读写的类。它们提供了更高级别的文本处理功能,使得读写文本数据变得更加方便和灵活。

原理

StreamReaderStreamWriter 通过将字节数据转换为字符数据,以及将字符数据转换为字节数据来实现文本数据的读写操作。它们内部使用了字符编码方式来进行字符和字节之间的转换,以确保在不同平台和环境下的兼容性。

案例

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // 使用 StreamWriter 写入文本数据
        using (StreamWriter writer = new StreamWriter("example.txt"))
        {
            writer.WriteLine("Hello, StreamWriter!");
        }

        // 使用 StreamReader 读取文本数据
        using (StreamReader reader = new StreamReader("example.txt"))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                Console.WriteLine(line);
            }
        }
    }
}

 应用场景

  • 文本文件读写:主要用于读取和写入文本文件中的数据,适用于处理各种文本文件,如配置文件、日志文件等。
  • 流数据处理:可用于处理流中的文本数据,如处理网络流、内存流等。
  • 数据转换:可用于将字节数据转换为字符数据,或者将字符数据转换为字节数据,用于在不同的数据源之间进行数据转换。

优点

  • 简单易用StreamReaderStreamWriter 提供了简单易用的接口,使得文本数据的读写变得更加方便。
  • 高级功能:提供了一些高级功能,如自动检测编码、自动换行等,提高了文本数据处理的灵活性和效率。
  • 字符编码支持:支持多种字符编码方式,能够在不同平台和环境下进行兼容处理。

缺点

  • 性能开销:由于需要进行字符和字节之间的转换,可能会引入一定的性能开销,特别是在处理大量数据时。
  • 不适合处理二进制数据:由于 StreamReaderStreamWriter 主要用于处理文本数据,不适合处理二进制数据。如果需要处理二进制数据,建议使用 BinaryReaderBinaryWriter 等类。

对比FileStream

特性

StreamReader / StreamWriter

FileStream

功能

用于读写文本数据

用于读写文件数据

基类

Stream

Stream

数据源

文件、流等

文件

读写方式

文本数据

字节数据

高级功能

自动检测编码、自动换行等

适用场景

文本文件读写、流数据处理、数据转换等

文件读写、二进制数据处理等

七、BinaryReader 和 BinaryWriter

简介

BinaryReaderBinaryWriter 是C#中用于读写二进制数据的类,它们分别用于从流中读取二进制数据并将二进制数据写入到流中。这两个类提供了对基本数据类型(如整数、浮点数等)和字节数组进行读写的方法,是处理二进制数据的常用工具。

原理

BinaryReaderBinaryWriter 基于字节流进行操作,通过将基本数据类型转换为字节序列来实现二进制数据的读写。它们提供了一系列的方法来读取和写入不同类型的数据,并使用适当的编码方式确保数据的正确读写。在底层,它们都是基于 Stream 类的实现,可以与不同类型的流(如 FileStreamMemoryStream 等)一起使用。

案例

using System;
using System.IO;

class Program
{
    static void Main()
    {
        // 写入二进制数据到文件
        using (BinaryWriter writer = new BinaryWriter(File.Open("example.bin", FileMode.Create)))
        {
            writer.Write(42);
            writer.Write(3.14);
            writer.Write("Hello, BinaryWriter!");
        }

        // 从文件中读取二进制数据
        using (BinaryReader reader = new BinaryReader(File.Open("example.bin", FileMode.Open)))
        {
            int intValue = reader.ReadInt32();
            double doubleValue = reader.ReadDouble();
            string stringValue = reader.ReadString();

            Console.WriteLine($"Int: {intValue}, Double: {doubleValue}, String: {stringValue}");
        }
    }
}

应用场景

  • 二进制文件处理:主要用于读写二进制文件,如处理自定义文件格式、读取和写入二进制配置文件等。
  • 网络通信:可用于在网络通信中读写二进制数据,如处理自定义网络协议等。
  • 序列化和反序列化:可以用于自定义对象的序列化和反序列化,将对象转换为二进制流进行存储或传输。

优点

  • 高效性:二进制数据的读写速度通常比文本数据快,尤其适用于处理大量数据。
  • 灵活性BinaryReaderBinaryWriter 提供了丰富的方法来读写各种类型的数据,具有很强的灵活性。
  • 直观:通过使用 ReadXXXWrite 等方法,可以直观地进行二进制数据的读写操作。

缺点

  • 不易阅读:二进制数据不易阅读和调试,相比于文本数据,调试时可能会更加困难。
  • 不适合人类交互:由于二进制数据的格式通常不易理解,因此不适合用于与用户进行交互式操作。

八、CryptoStream

简介

CryptoStream 是C#中用于在数据流上进行加密和解密操作的类,它派生自 Stream 类。通过 CryptoStream,可以在数据流传输过程中对数据进行加密和解密,提供了一种方便且高效的方式来保护数据的安全性。

原理

CryptoStream 基于加密算法,通过将原始数据流(如文件流、内存流等)包装在其内部,并使用指定的加密算法和密钥对数据进行加密或解密。在读取和写入数据时,CryptoStream 会自动进行加密或解密操作,从而实现数据的安全传输。

案例

using System;
using System.IO;
using System.Security.Cryptography;

class Program
{
    static void Main()
    {
        string plainText = "Hello, CryptoStream!";
        byte[] key = new byte[16]; // 密钥长度为16字节
        byte[] iv = new byte[16]; // 初始化向量长度为16字节

        using (Aes aesAlg = Aes.Create())
            using (MemoryStream ms = new MemoryStream())
        {
            // 创建 CryptoStream 进行加密操作
            using (CryptoStream csEncrypt = new CryptoStream(ms, aesAlg.CreateEncryptor(key, iv), CryptoStreamMode.Write))
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
            {
                // 写入数据到 CryptoStream
                swEncrypt.Write(plainText);
            }

            // 获取加密后的字节数组
            byte[] encryptedData = ms.ToArray();
            Console.WriteLine($"Encrypted data: {Convert.ToBase64String(encryptedData)}");

            // 创建 CryptoStream 进行解密操作
            using (MemoryStream decryptStream = new MemoryStream(encryptedData))
                using (CryptoStream csDecrypt = new CryptoStream(decryptStream, aesAlg.CreateDecryptor(key, iv), CryptoStreamMode.Read))
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
            {
                // 读取解密后的数据
                string decryptedText = srDecrypt.ReadToEnd();
                Console.WriteLine($"Decrypted data: {decryptedText}");
            }
        }
    }
}

 应用场景

  • 安全数据传输:主要用于在网络通信、文件传输等场景中保护数据的安全传输。
  • 数据存储:可用于加密和解密存储在本地文件或数据库中的敏感数据。
  • 加密算法实现:可以用于实现加密算法(如AES、DES等)的封装和使用,提供了对加密算法的统一接口。

优点

  • 数据安全性:通过加密算法对数据进行加密和解密,提供了数据的安全性保障。
  • 方便易用:作为 Stream 类的一个子类,CryptoStream 提供了与其他数据流类相似的使用方式,易于集成到现有的代码中。
  • 灵活性:支持多种加密算法和模式,可以根据需要选择合适的加密算法和参数。

缺点

  • 性能开销:加密和解密操作可能会引入一定的性能开销,特别是在处理大量数据时。
  • 密钥管理:需要妥善管理加密算法所使用的密钥,密钥的安全性直接影响到加密数据的安全性。

九、DeflateStream

简介

DeflateStream 是C#中用于对数据流进行压缩和解压缩的类,它派生自 Stream 类。通过 DeflateStream,可以在数据传输过程中对数据进行压缩,以减少数据传输量,或者对接收到的压缩数据进行解压缩,恢复原始数据。

原理

DeflateStream 基于 DEFLATE 压缩算法,是一种流式压缩算法,常用于数据传输中。在压缩过程中,DeflateStream 将数据流中的数据进行压缩,减少数据的大小;在解压缩过程中,它会将压缩的数据流解压缩为原始数据流。DeflateStream 使用的压缩算法是无损的,即压缩后的数据可以完全恢复为原始数据。

案例

using System;
using System.IO;
using System.IO.Compression;

class Program
{
    static void Main()
    {
        string text = "Hello, DeflateStream! This is a test for compression.";

        // 压缩数据
        byte[] compressedData;
        using (MemoryStream ms = new MemoryStream())
        {
            using (DeflateStream deflateStream = new DeflateStream(ms, CompressionMode.Compress))
                using (StreamWriter writer = new StreamWriter(deflateStream))
            {
                writer.Write(text);
            }
            compressedData = ms.ToArray();
        }

        Console.WriteLine($"Compressed data: {Convert.ToBase64String(compressedData)}");

        // 解压缩数据
        using (MemoryStream compressedMs = new MemoryStream(compressedData))
            using (DeflateStream deflateStream = new DeflateStream(compressedMs, CompressionMode.Decompress))
            using (StreamReader reader = new StreamReader(deflateStream))
        {
            string decompressedText = reader.ReadToEnd();
            Console.WriteLine($"Decompressed text: {decompressedText}");
        }
    }
}

应用场景

  • 网络传输:在网络传输中,可用于减少数据传输量,提高传输效率。
  • 文件压缩:在文件压缩和解压缩中,用于减少文件大小,节省存储空间。
  • 内存占用优化:在内存中对数据进行压缩,可以减少内存占用,提高系统性能。

优点

  • 减少数据传输量:通过压缩数据流,可以减少数据传输量,提高传输效率。
  • 无损压缩:使用 DEFLATE 压缩算法,压缩后的数据可以完全恢复为原始数据。
  • 易于使用:作为 Stream 类的一个子类,DeflateStream 提供了与其他数据流类相似的使用方式,易于集成到现有的代码中。

缺点

  • 性能开销:压缩和解压缩操作可能会引入一定的性能开销,特别是在处理大量数据时。
  • 压缩率受限:DEFLATE 压缩算法的压缩率有限,对于某些类型的数据可能不如其他压缩算法效果好。
posted @ 2024-03-18 09:24  咸鱼翻身?  阅读(237)  评论(0编辑  收藏  举报