0

0

C#的StreamReader和StreamWriter如何读写文本?

煙雲

煙雲

发布时间:2025-08-15 09:40:02

|

666人浏览过

|

来源于php中文网

原创

streamreader用于读取文本文件,streamwriter用于写入文本文件,二者均基于stream类,支持文件流、内存流和网络流;2. 读取文本时可使用readline()逐行读取、readtoend()读取全部内容(慎用于大文件)或read()按字符读取;3. 写入文本时使用write()或writeline()方法,可指定是否追加到文件;4. 应显式指定编码(如utf-8、utf-16)以正确处理不同编码的文本文件;5. 处理大文件时应使用缓冲区分块读取或逐行处理,避免内存溢出;6. 与binaryreader/binarywriter不同,streamreader/streamwriter处理文本并自动管理编码,后者用于二进制数据读写;7. 可结合cryptostream实现加密解密,通过aes算法和密码派生密钥对文件内容进行安全保护,需妥善管理密钥和密码。

C#的StreamReader和StreamWriter如何读写文本?

C# 中的

StreamReader
StreamWriter
类是用于读写文本文件的核心工具。它们提供了一种方便且高效的方式来处理文本数据,而无需手动处理字节编码的复杂性。

解决方案:

StreamReader
用于从流中读取文本,而
StreamWriter
用于将文本写入流。 它们都依赖于
Stream
类,这意味着它们可以与各种流一起使用,包括文件流、内存流和网络流。

使用

StreamReader
读取文本:

  1. 创建

    StreamReader
    实例: 可以通过传入
    Stream
    对象或文件路径来创建
    StreamReader
    实例。 例如,从文件中读取:

    string filePath = "myFile.txt";
    try
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            // 读取操作将在 using 块中进行
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"读取文件时发生错误:{ex.Message}");
    }
  2. 读取文本:

    StreamReader
    提供了多种读取文本的方法,例如:

    • ReadLine()
      : 读取一行文本,返回字符串。 如果到达流的末尾,则返回
      null
    • ReadToEnd()
      : 读取从当前位置到流末尾的所有文本,返回字符串。 谨慎使用,特别是对于大型文件,因为它可能导致内存问题。
    • Read()
      : 读取一个字符或一组字符。

    示例:

    using (StreamReader reader = new StreamReader(filePath))
    {
        string? line;
        while ((line = reader.ReadLine()) != null)
        {
            Console.WriteLine(line);
        }
    }
  3. 处理编码: 默认情况下,

    StreamReader
    使用 UTF-8 编码。 如果文件使用不同的编码,则需要在创建
    StreamReader
    实例时指定编码。

    using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
    {
        // ...
    }

使用

StreamWriter
写入文本:

  1. 创建

    StreamWriter
    实例: 类似于
    StreamReader
    ,可以通过传入
    Stream
    对象或文件路径来创建
    StreamWriter
    实例。 可以指定是否追加到现有文件。

    string filePath = "myFile.txt";
    try
    {
        using (StreamWriter writer = new StreamWriter(filePath)) // 默认覆盖现有文件
        {
            // 写入操作将在 using 块中进行
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"写入文件时发生错误:{ex.Message}");
    }
    
    // 追加到文件
    try
    {
        using (StreamWriter writer = new StreamWriter(filePath, true)) // true 表示追加
        {
            // 写入操作将在 using 块中进行
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"写入文件时发生错误:{ex.Message}");
    }
  2. 写入文本:

    StreamWriter
    提供了多种写入文本的方法,例如:

    • Write()
      : 写入一个字符、字符串或对象。
    • WriteLine()
      : 写入一个字符、字符串或对象,后跟一个行终止符。

    示例:

    using (StreamWriter writer = new StreamWriter(filePath))
    {
        writer.WriteLine("Hello, world!");
        writer.Write("This is a test.");
    }
  3. 处理编码:

    StreamReader
    类似,
    StreamWriter
    默认使用 UTF-8 编码。 可以指定不同的编码。

    移动端无限滚动加载瀑布流
    移动端无限滚动加载瀑布流

    里面有2个文件夹。其中这个文件名是:finishing,是我项目还没有请求后台的数据的模拟写法。请求后台数据之后,瀑布流的js有一点点变化,放在文件名是:finished。变化在于需要穿参数到后台,和填充的内容都用后台的数据填充。看自己项目需求来。由于chrome模拟器是不允许读取本地文件json的,所以如果你要进行测试,在hbuilder打开项目就可以看到效果啦,或者是火狐浏览器。

    下载
    using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.UTF8))
    {
        // ...
    }
  4. 自动刷新: 默认情况下,

    StreamWriter
    会缓冲输出。 可以通过设置
    AutoFlush
    属性来启用自动刷新。

    using (StreamWriter writer = new StreamWriter(filePath))
    {
        writer.AutoFlush = true;
        // ...
    }

最佳实践:

  • 始终将
    StreamReader
    StreamWriter
    实例包装在
    using
    语句中,以确保正确释放资源,即使发生异常也是如此。
  • 显式指定编码,以避免编码问题。
  • 对于大型文件,避免使用
    ReadToEnd()
    ,因为它可能导致内存问题。 考虑逐行读取或使用
    Read()
    方法分块读取。
  • 根据需要启用自动刷新,以确保数据及时写入流。

如何高效处理大型文本文件?

处理大型文本文件时,效率至关重要。

ReadToEnd()
可能会导致内存溢出。 逐行读取是一个更安全的选择,但仍然可能很慢。 另一种方法是使用缓冲区来读取和写入数据块。

// 使用缓冲区读取大文件
using (FileStream fileStream = new FileStream("largefile.txt", FileMode.Open, FileAccess.Read))
{
    using (BufferedStream bufferedStream = new BufferedStream(fileStream))
    {
        using (StreamReader streamReader = new StreamReader(bufferedStream))
        {
            char[] buffer = new char[4096]; // 4KB 缓冲区
            int bytesRead;
            while ((bytesRead = streamReader.Read(buffer, 0, buffer.Length)) > 0)
            {
                // 处理 buffer 中的数据 (0 到 bytesRead)
                string chunk = new string(buffer, 0, bytesRead);
                Console.Write(chunk); // 示例:打印到控制台
            }
        }
    }
}

这种方法将文件分成更小的块,从而减少了内存消耗。 还可以考虑使用异步读取操作,以避免阻塞主线程。

如何处理不同编码的文本文件?

文本文件可以使用不同的编码进行编码,例如 UTF-8、UTF-16、ASCII 等。 如果不指定正确的编码,

StreamReader
StreamWriter
可能会错误地解释文本。

可以使用

Encoding
类来指定编码。 例如,要使用 UTF-16 编码读取文件:

using (StreamReader reader = new StreamReader("utf16file.txt", Encoding.Unicode))
{
    string? line;
    while ((line = reader.ReadLine()) != null)
    {
        Console.WriteLine(line);
    }
}

如果不知道文件的编码,可以尝试使用

Encoding.GetEncoding
方法来自动检测编码。 但是,这种方法并不总是可靠的。

StreamReader
StreamWriter
BinaryReader
BinaryWriter
区别是什么?

StreamReader
StreamWriter
用于读写文本数据,而
BinaryReader
BinaryWriter
用于读写二进制数据。
StreamReader
StreamWriter
会自动处理文本编码,而
BinaryReader
BinaryWriter
则不会。

如果需要读写文本数据,请使用

StreamReader
StreamWriter
。 如果需要读写二进制数据,请使用
BinaryReader
BinaryWriter
。 例如,读取一个整数,需要使用
BinaryReader.ReadInt32()
。 如果使用
StreamReader
, 则需要先读取字符串,再将字符串解析为整数。

// BinaryReader 示例
using (FileStream fileStream = new FileStream("binarydata.dat", FileMode.Open, FileAccess.Read))
{
    using (BinaryReader binaryReader = new BinaryReader(fileStream))
    {
        int age = binaryReader.ReadInt32();
        double salary = binaryReader.ReadDouble();
        Console.WriteLine($"Age: {age}, Salary: {salary}");
    }
}

如何使用
StreamReader
StreamWriter
进行文件加密?

虽然

StreamReader
StreamWriter
本身不提供加密功能,但可以将它们与加密流结合使用来实现文件加密。 例如,可以使用
CryptoStream
类来加密和解密数据。

以下是一个简单的加密和解密文件的示例:

using System.Security.Cryptography;

// 加密文件
public static void EncryptFile(string inputFile, string outputFile, string password)
{
    byte[] salt = new byte[8];
    RandomNumberGenerator rng = RandomNumberGenerator.Create();
    rng.GetBytes(salt);

    using (FileStream fsOutput = new FileStream(outputFile, FileMode.Create))
    {
        using (Aes aesAlg = Aes.Create())
        {
            Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt, 1000, HashAlgorithmName.SHA256);
            aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
            aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8);

            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            using (CryptoStream csEncrypt = new CryptoStream(fsOutput, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    //Write salt to the beginning of the file.
                    fsOutput.Write(salt, 0, salt.Length);
                    //Write the rest of the file.
                    using (StreamReader sr = new StreamReader(inputFile))
                    {
                        swEncrypt.Write(sr.ReadToEnd());
                    }
                }
            }
        }
    }
}

// 解密文件
public static void DecryptFile(string inputFile, string outputFile, string password)
{
    byte[] salt = new byte[8];
    using (FileStream fsInput = new FileStream(inputFile, FileMode.Open))
    {
        fsInput.Read(salt, 0, salt.Length);

        using (Aes aesAlg = Aes.Create())
        {
            Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt, 1000, HashAlgorithmName.SHA256);
            aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
            aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8);

            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
            using (CryptoStream csDecrypt = new CryptoStream(fsInput, decryptor, CryptoStreamMode.Read))
            {
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {
                    using (StreamWriter sw = new StreamWriter(outputFile))
                    {
                        sw.Write(srDecrypt.ReadToEnd());
                    }
                }
            }
        }
    }
}

请注意,这只是一个简单的示例,可能不适用于所有情况。 应该根据具体需求选择合适的加密算法和密钥管理策略。 此外,需要妥善保管密码,否则无法解密文件。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

229

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

433

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

205

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1435

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

609

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

547

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

539

2024.04.29

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.7万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 10.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号