亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#中的 StreamReader/StreamWriter 使用示例詳解

 更新時間:2025年03月27日 11:10:06   作者:鯉籽鯤  
在 C# 開發(fā)中,StreamReader 和 StreamWriter 是處理文本文件的核心類,屬于 System.IO 命名空間,本文將從基礎(chǔ)到高級用法,結(jié)合代碼示例,全面解析其核心功能、性能優(yōu)化及常見問題解決方案,感興趣的朋友一起看看吧

前言

在 C# 開發(fā)中,StreamReaderStreamWriter 是處理文本文件的核心類,屬于 System.IO 命名空間。它們基于流(Stream)操作文本數(shù)據(jù),支持讀寫、編碼設(shè)置、異步操作等,適用于日志記錄、配置文件處理、數(shù)據(jù)導(dǎo)出等場景。本文將從基礎(chǔ)到高級用法,結(jié)合代碼示例,全面解析其核心功能、性能優(yōu)化及常見問題解決方案。

一、什么是 StreamReader 和 StreamWriter?

1. 定義

  • StreamReader:用于從流(如文件、網(wǎng)絡(luò)流)中讀取文本數(shù)據(jù),支持逐行讀取、讀取指定長度數(shù)據(jù)或一次性讀取全部內(nèi)容。
  • StreamWriter:用于向流中寫入文本數(shù)據(jù),支持追加模式、格式化輸出及自定義編碼。

StreamReaderStreamWriterSystem.IO 命名空間中的兩個類,它們分別用于讀取和寫入文本數(shù)據(jù)。兩者均繼承自 TextReaderTextWriter 抽象類,通常與 FileStream、MemoryStream 等流結(jié)合使用。

2. 特點(diǎn)

  • 提供了方便的方法來讀取和寫入文本數(shù)據(jù),支持多種編碼格式。
  • 可以處理大文件,通過流的方式逐步讀取或?qū)懭霐?shù)據(jù),節(jié)省內(nèi)存。
  • 支持異步操作,提高程序的響應(yīng)性和性能。

3. 用途

  • 文本文件讀寫
    • 替代 FileStream 直接操作字節(jié)的復(fù)雜性,自動處理編碼和換行符。如日志文件、配置文件等。
  • 網(wǎng)絡(luò)流解析
    • NetworkStream 結(jié)合,實(shí)現(xiàn) HTTP 響應(yīng)內(nèi)容的高效解碼。
  • 內(nèi)存流操作
    • 配合 MemoryStream 處理內(nèi)存中的文本緩存,如 JSON/XML 序列化。
  • 日志與數(shù)據(jù)記錄: 支持追加模式寫入,避免頻繁覆蓋文件內(nèi)容。

適用于以下場景:

  • 日志記錄:將日志追加到文件。
  • 配置文件操作:讀取 .ini.json 等文本配置。
  • 數(shù)據(jù)導(dǎo)出:將數(shù)據(jù)寫入 CSV、TXT 文件。

4. 為什么需要 StreamReader/StreamWriter?

在C#中處理文本文件時,直接使用 FileStream 操作字節(jié)數(shù)組不僅繁瑣,還需手動處理編碼、換行符等問題。StreamReaderStreamWriter 提供了更高級的文本流操作接口,支持自動編碼檢測、換行符處理及便捷的讀寫方法,大幅簡化開發(fā)流程。

二、基礎(chǔ)用法

1. 創(chuàng)建 StreamReader 和 StreamWriter 對象

在 C# 中,有多種方式可以創(chuàng)建 StreamReaderStreamWriter 對象:

1)從文件路徑創(chuàng)建

使用文件路徑創(chuàng)建 StreamReaderStreamWriter 對象是最常見的方法。
自動處理編碼(默認(rèn)UTF-8)

using System.IO;
// 創(chuàng)建 StreamReader
using (StreamReader reader = new StreamReader("example.txt"))
{
    // 讀取操作
}
// 創(chuàng)建 StreamWriter
using (StreamWriter writer = new StreamWriter("example.txt"))
{
    // 寫入操作
}

2)從流創(chuàng)建

也可以從現(xiàn)有的流 Stream對象創(chuàng)建 StreamReaderStreamWriter,例如從 MemoryStream 或網(wǎng)絡(luò)流、 FileStream,適合復(fù)雜場景。

using System.IO;
// 從 MemoryStream 創(chuàng)建
MemoryStream memoryStream = new MemoryStream();
StreamReader reader = new StreamReader(memoryStream);
StreamWriter writer = new StreamWriter(memoryStream);
// 從 FileStream 創(chuàng)建
FileStream fs = new FileStream("data.bin", FileMode.Open);
using (StreamReader sr = new StreamReader(fs)) { /*...*/ }

3)編碼與格式設(shè)置

? 指定編碼

默認(rèn)編碼為 UTF-8,但可通過構(gòu)造函數(shù)指定其他編碼(如 UTF-16ASCII):

// 使用 UTF-16 編碼
using (StreamWriter writer = new StreamWriter("data.txt", false, Encoding.Unicode))
{
    writer.WriteLine("Hello, Unicode!");
}

? 追加寫入模式

通過指定StreamWriterappend參數(shù)為true 設(shè)置為 追加寫入(append: true)。

StreamWriter sw = new StreamWriter("log.txt", true, Encoding.UTF8); // 追加模式

? 控制底層流是否關(guān)閉

leaveOpen:控制底層流是否隨讀寫器關(guān)閉(默認(rèn) false)。

MemoryStream  ms= new MemoryStream();
StreamReader streamReader = new StreamReader(ms, Encoding.Unicode, leaveOpen: true);

? 自動檢測編碼

通過 StreamReaderDetectEncodingFromByteOrderMarks 屬性,自動識別 BOM 標(biāo)記:

using (StreamReader reader = new StreamReader("data.txt", Encoding.UTF8, detectEncodingFromByteOrderMarks:true))
{
    // 如果文件開頭有 BOM,會自動檢測編碼
    string content = reader.ReadToEnd();
}

2. 使用 StreamWriter 寫入數(shù)據(jù)

StreamWriter 提供了多種方法來寫入文本數(shù)據(jù),最常用的是 WriteWriteLine 方法。

1)寫入數(shù)據(jù)

使用 Write 方法可以寫入數(shù)據(jù)到文件中。支持字符串、數(shù)值等類型。

using (StreamWriter writer = new StreamWriter("example.txt"))
{
	// 寫入不同類型的數(shù)據(jù)
	writer.Write(1.1f);
	writer.Write(42);
	writer.Write(new byte[] { 1, 2, 3 });
    writer.Write("Hello, World!");
}

2)寫入帶換行符的數(shù)據(jù)

使用 WriteLine 方法可以寫入一個帶換行符的數(shù)據(jù)。支持字符串、數(shù)值等類型。

using (StreamWriter writer = new StreamWriter("example.txt"))
{
	// 寫入不同類型的數(shù)據(jù)
	writer.WriteLine(1.1f);
	writer.WriteLine(42);
	writer.WriteLine(new byte[] { 1, 2, 3 });
    writer.WriteLine("Hello, World!");
}

3. 使用 StreamReader 讀取數(shù)據(jù)

StreamReader 提供了多種方法來讀取文本數(shù)據(jù),最常用的是 ReadReadLineReadToEnd 方法。

1)讀取字符

使用 Read 方法可以讀取一個字符。

using (StreamReader reader = new StreamReader("example.txt"))
{
    int character;
    while ((character = reader.Read()) != -1)
    {
        Console.Write((char)character);
    }
}

2)讀取一行

使用 ReadLine 方法可以讀取一行文本。

using (StreamReader reader = new StreamReader("example.txt"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        Console.WriteLine(line);
    }
}

3)讀取所有文本

使用 ReadToEnd 方法可以讀取整個文件的內(nèi)容。

using (StreamReader reader = new StreamReader("example.txt"))
{
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
}

批量操作ReadToEnd() 一次性讀取全文,Write() 支持字符數(shù)組寫入。

4. StreamReader 和 StreamWriter 的常用屬性和方法

1)StreamReader的常用屬性和方法

  • BaseStream:獲取StreamReader所使用的基礎(chǔ)流。
  • CurrentEncoding:獲取當(dāng)前使用的字符編碼。
  • EndOfStream:指示是否已到達(dá)流的末尾。
  • Peek:查看下一個字符而不讀取它。
  • Read:讀取單個字符或字符數(shù)組。
  • ReadBlock:讀取指定數(shù)量的字符。
  • ReadLine:讀取一行文本。
  • ReadToEnd:讀取流中的所有文本。

2)StreamWriter的常用屬性和方法

  • BaseStream:獲取StreamWriter所使用的基礎(chǔ)流。
  • AutoFlush:獲取或設(shè)置一個值,該值指示是否在寫入數(shù)據(jù)后自動刷新流。
  • Encoding:獲取當(dāng)前使用的字符編碼。
  • Write:寫入指定的數(shù)據(jù)。
  • WriteLine:寫入指定的數(shù)據(jù),并添加換行符。
  • Flush:將所有緩沖的字符寫入基礎(chǔ)流。
  • Close:關(guān)閉流并釋放所有相關(guān)資源。

3)使用示例

? 獲取當(dāng)前編碼

可以使用 CurrentEncoding 屬性獲取當(dāng)前使用的編碼。

using (StreamReader reader = new StreamReader("example.txt"))
{
    Encoding encoding = reader.CurrentEncoding;
    Console.WriteLine("Encoding: " + encoding.EncodingName);
}

? 獲取基礎(chǔ)流對象

使用 BaseStream 屬性可以獲取基礎(chǔ)流對象。

using (StreamReader reader = new StreamReader("example.txt"))
{
    Stream stream = reader.BaseStream;
    // 操作流
}

? 指示是否已到達(dá)流的末尾

  while (!sr.EndOfStream) 
  {
      string line = sr.ReadLine();
      Console.WriteLine(line);
  }

5. 示例代碼

下面是一個完整的示例,演示了如何使用 StreamReaderStreamWriter

class Program
{
    static void Main()
    {
        string filePath = "example.txt";
        // 使用 StreamWriter 寫入數(shù)據(jù)
        using (StreamWriter writer = new StreamWriter(filePath))
        {
            writer.WriteLine("Hello, World!");
            writer.WriteLine("This is a new line.");
            writer.WriteLine("The answer is: 42");
        }
        // 使用 StreamReader 讀取數(shù)據(jù)
        using (StreamReader reader = new StreamReader(filePath))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                Console.WriteLine(line);
            }
        }
        // 使用 StreamReader 讀取數(shù)據(jù) + EndOfStream 屬性判斷
        using (StreamReader reader = new StreamReader(filePath))
        {
            while (!reader.EndOfStream)
            {
                Console.WriteLine(reader.ReadLine());
            }
        }
        // 讀取整個文件內(nèi)容
        using (StreamReader reader = new StreamReader(filePath))
        {
            Console.WriteLine(reader.ReadToEnd());
        }
        string content = File.ReadAllText(filePath);
        Console.WriteLine("File content:");
        Console.WriteLine(content);
        // 讀取字符
        using (StreamReader reader = new StreamReader(filePath))
        {
            int character;
            while ((character = reader.Read()) != -1)
            {
                Console.Write((char)character);
            }
        }
    }
}

通過這個示例,我們可以看到 StreamReaderStreamWriter 在處理文本文件時是多么方便和高效。它們提供了豐富的功能,滿足了多種文本處理需求。

三、高級用法

1. 高級技巧

1)異步操作

使用 ReadAsync、WriteAsync 實(shí)現(xiàn)異步讀寫,避免阻塞主線程,提升I/O性能

public async Task WriteAsync()
{
    using (StreamWriter writer = new StreamWriter("data.txt"))
    {
        await writer.WriteLineAsync("異步寫入");
    }
}
public async Task ReadAsync()
{
    using (StreamReader reader = new StreamReader("data.txt"))
    {
        string content = await reader.ReadToEndAsync();
    }
}

2)緩沖區(qū)優(yōu)化

預(yù)分配容量:若已知文件大小,初始化時指定 bufferSize 減少擴(kuò)容開銷。 平衡性能與內(nèi)存占用

// 創(chuàng)建帶自定義緩沖區(qū)的流
using (StreamReader reader = new StreamReader("data.txt", Encoding.UTF8, true, 8192))
{
    // 緩沖區(qū)大小為 8KB
}

3)大文件處理

逐行讀取大文件以避免內(nèi)存溢出:

using (StreamReader reader = new StreamReader("large_file.txt"))
{
    string line;
    while ((line = await reader.ReadLineAsync()) != null)
    {
        // 處理每一行
    }
}

4)顯式刷新緩沖區(qū)

  • 顯式刷新緩沖區(qū):高頻寫入時調(diào)用 Flush() 避免內(nèi)存堆積。
  • 延遲寫入與批量提交
sw.AutoFlush = false;  // 關(guān)閉自動刷新
for (int i = 0; i < 1000; i++) {
    sw.Write($"Data {i}");
}
sw.Flush();  // 手動批量提交

2. 高級應(yīng)用示例

1)案例1:CSV文件解析

假設(shè)需讀取包含逗號分隔的CSV文件并提取數(shù)據(jù):

using (StreamReader sr = new StreamReader("data.csv")) 
{
    while (!sr.EndOfStream) 
    {
        string line = sr.ReadLine();
        string[] fields = line.Split(',').Select(f => f.Trim()).ToArray();
        // 處理字段數(shù)據(jù)...
    }
}

優(yōu)勢:自動處理編碼與換行符,簡化字符串分割邏輯。

2)案例2:大文件逐行處理與內(nèi)存優(yōu)化

當(dāng)處理 GB 級日志文件時,需避免一次性加載全部數(shù)據(jù)導(dǎo)致內(nèi)存溢出:

using (var sr = new StreamReader("large.log", Encoding.UTF8, bufferSize: 8192)) 
{
    while (!sr.EndOfStream) 
    {
        string line = sr.ReadLine();
        if (line.Contains("ERROR")) 
        {
            // 實(shí)時處理錯誤行
        }
    }
}

優(yōu)化點(diǎn):

  • 設(shè)置 bufferSize 為 8KB(默認(rèn) 1KB),減少磁盤讀取次數(shù)。
  • 逐行釋放內(nèi)存,避免 ReadToEnd() 的全量加載風(fēng)險。

3)案例3:日志記錄系統(tǒng)

public static void Log(string message)
{
    using var writer = new StreamWriter("app.log", true);
    writer.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}");
}

4)案例4:配置文件讀寫

var config = new Dictionary<string, string>();
using var reader = new StreamReader("config.ini");
while ((line = reader.ReadLine()) != null)
{
    var parts = line.Split('=');
    if (parts.Length == 2)
    {
        config[parts[0]] = parts[1];
    }
}

四、常見問題與最佳實(shí)踐

1. 常見問題

1)文件不存在時的異常

try
{
    using (StreamReader reader = new StreamReader("non_existent.txt"))
    {
        // 處理文件
    }
}
catch (FileNotFoundException ex)
{
    Console.WriteLine("文件不存在:" + ex.Message);
}

2)編碼不匹配導(dǎo)致亂碼

確保讀寫時編碼一致:

// 寫入時使用 UTF-8
using (StreamWriter writer = new StreamWriter("data.txt", false, Encoding.UTF8)) { ... }
// 讀取時指定相同編碼
using (StreamReader reader = new StreamReader("data.txt", Encoding.UTF8)) { ... }

3)資源未釋放

始終使用 using 語句確保流正確關(guān)閉:

// 錯誤示例:未使用 using
StreamReader reader = new StreamReader("data.txt");
// ... 處理后未關(guān)閉,可能導(dǎo)致文件被鎖定
reader.Close(); // 需手動調(diào)用
// 正確做法:使用 using 自動釋放資源
using (StreamReader reader = new StreamReader("data.txt")) { ... }
// C# 8+簡化寫法
using var writer = new StreamWriter("output.txt");

4)編碼問題

若文件包含BOM(字節(jié)順序標(biāo)記),可通過 detectEncodingFromByteOrderMarks: true 自動識別。
處理含 BOM 頭的多編碼文件時,自動適配編碼:

using (FileStream fs = File.OpenRead("mixed_encoding.txt")) 
{
    using (StreamReader sr = new StreamReader(fs, Encoding.Default, detectEncodingFromByteOrderMarks: true)) 
    {
        Console.WriteLine($"檢測到編碼:{sr.CurrentEncoding}");
        // 按正確編碼解析內(nèi)容
    }
}

技巧:通過 CurrentEncoding 屬性獲取實(shí)際使用的編碼。

5)流位置重置

寫入后需調(diào)用 Seek(0, SeekOrigin.Begin) 重置位置,否則后續(xù)讀取會從末尾開始。

6)避免嵌套流生命周期

避免嵌套流生命周期:確保底層流與讀寫器釋放順序一致(先關(guān)讀寫器,再關(guān)流)。

2. 最佳實(shí)踐總結(jié)

  • 資源管理:必須使用using語句
  • 編碼明確:盡量指定確定編碼
  • 異常處理:全面捕獲IO異常
  • 性能考量:大文件使用緩沖讀取
  • 模式選擇:追加模式注意參數(shù)設(shè)置

到此這篇關(guān)于C#中的 StreamReader/StreamWriter 使用示例詳解的文章就介紹到這了,更多相關(guān)C# StreamReader/StreamWriter 使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#中struct與class的區(qū)別詳解

    C#中struct與class的區(qū)別詳解

    本文主要介紹了C#中struct與class的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C#使用dynamic類型訪問JObject對象

    C#使用dynamic類型訪問JObject對象

    這篇文章主要為大家詳細(xì)介紹了C#使用dynamic類型訪問JObject對象,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • C#圖像處理之浮雕效果實(shí)現(xiàn)方法

    C#圖像處理之浮雕效果實(shí)現(xiàn)方法

    這篇文章主要介紹了C#圖像處理之浮雕效果實(shí)現(xiàn)方法,可實(shí)現(xiàn)圖片轉(zhuǎn)換成浮雕效果的功能,需要的朋友可以參考下
    2015-04-04
  • 解析C#彩色圖像灰度化算法的實(shí)現(xiàn)代碼詳解

    解析C#彩色圖像灰度化算法的實(shí)現(xiàn)代碼詳解

    本篇文章是對C#中彩色圖像灰度化算法的實(shí)現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C#使用iTextSharp獲取PDF文件書簽信息的操作方法

    C#使用iTextSharp獲取PDF文件書簽信息的操作方法

    C# iTextSharp是一個用于處理PDF文件的源庫,它提供了一系列的功能,包括創(chuàng)建PDF文件,以及提取和操作PDF文件中的內(nèi)容,本文給大家介紹了C#使用iTextSharp獲取PDF文件書簽信息的操作方法,需要的朋友可以參考下
    2024-04-04
  • C#中分部類和分部方法的應(yīng)用

    C#中分部類和分部方法的應(yīng)用

    本篇文章介紹了,C#中分部類和分部方法的應(yīng)用。需要的朋友參考下
    2013-04-04
  • C#數(shù)據(jù)類型實(shí)現(xiàn)背包、隊列和棧

    C#數(shù)據(jù)類型實(shí)現(xiàn)背包、隊列和棧

    本文詳細(xì)講解了C#數(shù)據(jù)結(jié)構(gòu)類型,并實(shí)現(xiàn)背包、隊列和棧的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • C#并行編程之Task同步機(jī)制

    C#并行編程之Task同步機(jī)制

    這篇文章介紹了C#并行編程之Task同步機(jī)制,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • 如何用C#創(chuàng)建用戶自定義異常淺析

    如何用C#創(chuàng)建用戶自定義異常淺析

    雖然在 C# 語言中已經(jīng)提供了很多異常處理類,但在實(shí)際編程中還是會遇到未涉及的一些異常處理,這篇文章主要給大家介紹了關(guān)于如何用C#創(chuàng)建用戶自定義異常的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • C#實(shí)現(xiàn)二維數(shù)據(jù)數(shù)組導(dǎo)出到Excel的詳細(xì)過程

    C#實(shí)現(xiàn)二維數(shù)據(jù)數(shù)組導(dǎo)出到Excel的詳細(xì)過程

    將數(shù)據(jù)庫查詢出來的數(shù)據(jù)導(dǎo)出并生成?Excel?文件,是項目中經(jīng)常使用的一項功能,本文將介紹通過數(shù)據(jù)集生成二維數(shù)據(jù)數(shù)組并導(dǎo)出到?Excel,文中有詳細(xì)的代碼供大家參考,需要的朋友可以參考下
    2024-09-09

最新評論