WPF學習(五)

文章目錄

  • 一、FileStream和StreamWriter理解
    • 1.1、具體關系解析
    • 1.2、類比理解
    • 1.3、總結
    • 1.4、示例代碼
    • 1.5、 WriteLine()和 Write()的區別
    • 1.6、 StreamWriter.Close的作用
  • 二、

一、FileStream和StreamWriter理解

在 C# 中,StreamWriterFileStream協作關系,二者共同完成文件的文本寫入操作,但職責不同。簡單來說:
FileStream 負責底層的 字節級文件操作(如打開、讀取、寫入字節),而 StreamWriter 基于 FileStream 提供 文本編碼轉換和便捷的文本寫入功能(如直接寫入字符串、換行等)。

1.1、具體關系解析

  1. 依賴關系
    StreamWriter 的構造函數需要接收一個 Stream 類型的參數(FileStreamStream 的子類),即 StreamWriter 必須依賴一個底層流(如 FileStream)才能工作。
    例:new StreamWriter(aFile) 中,aFileFileStream)是 StreamWriter 的“數據源/目標”。

  2. 功能分工

    • FileStream:處理與操作系統交互的底層細節,比如:
      • 打開文件并獲取文件句柄
      • 以字節(byte)為單位讀寫數據
      • 控制文件的打開模式(FileMode)、訪問權限(FileAccess)、共享模式(FileShare)等。
    • StreamWriter:在 FileStream 之上封裝了文本處理邏輯,比如:
      • 將字符串自動編碼為字節(默認 UTF-8,可指定編碼)
      • 提供 WriteLine() 等便捷方法(自動處理換行符 \r\n
      • 內部維護緩沖區,減少頻繁的底層 IO 操作,提升性能。
  3. 生命周期關聯
    StreamWriter 被釋放(如 using 語句結束)時,會自動刷新緩沖區并關閉其依賴的 FileStream(除非構造時指定 leaveOpen: true)。
    例:若希望釋放 StreamWriter 后仍保留 FileStream 用于其他操作,可這樣寫:

    using (FileStream aFile = new FileStream("Log.txt", FileMode.OpenOrCreate))
    {// leaveOpen: true 表示釋放 StreamWriter 時不關閉 FileStreamusing (StreamWriter sw = new StreamWriter(aFile, leaveOpen: true)){sw.WriteLine("Hello");}// 此時 aFile 仍可繼續使用(如讀取字節)
    }
    

1.2、類比理解

可以把二者的關系類比為“水管”和“水龍頭”:

  • FileStream水管:負責連接水源(文件),提供原始的水流(字節)傳輸通道。
  • StreamWriter帶過濾功能的水龍頭:安裝在水管上,將原始水流(字節)轉換為符合需求的“飲用水”(字符串),并提供便捷的開關(寫入方法)。

1.3、總結

  • FileStream 是底層字節流,處理文件的物理操作;
  • StreamWriter 是高層文本包裝器,依賴 FileStream 實現字符串到字節的轉換和便捷寫入。
  • 二者結合使用,既利用了 FileStream 的底層控制能力,又通過 StreamWriter 簡化了文本處理。

1.4、示例代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;namespace StreamWrite
{class Program{static void Main(string[] args){try{FileStream aFile = new FileStream("Log.txt", FileMode.OpenOrCreate);StreamWriter sw = new StreamWriter(aFile);bool truth = true;// Write data to file.sw.WriteLine("Hello to you.");sw.WriteLine("It is now {0} and things are looking good.",DateTime.Now.ToLongDateString());sw.Write("More than that,");sw.Write(" it's {0} that C# is fun.", truth);sw.Close();}catch(IOException e){Console.WriteLine("An IO exception has been thrown!");Console.WriteLine(e.ToString());Console.ReadLine();return;}}}
}

在這里插入圖片描述

1.5、 WriteLine()和 Write()的區別

            sw.WriteLine("Hello to you.");sw.WriteLine("It is now {0} and things are looking good.",DateTime.Now.ToLongDateString());sw.Write("More than that,");

在 C# 的 StreamWriter 類中,WriteLine()Write() 是兩個常用的寫入方法,它們的核心區別在于 是否自動添加換行符。以下是詳細對比:

一、核心區別

方法是否添加換行符寫入后光標位置示例代碼效果
WriteLine()? 自動添加移至下一行開頭sw.WriteLine("A"); sw.WriteLine("B"); → 文件內容:
A
B
Write()? 不添加留在當前行末尾sw.Write("A"); sw.Write("B"); → 文件內容:
AB

二、示例對比
假設你有以下代碼:

using (StreamWriter sw = new StreamWriter("test.txt"))
{sw.Write("第一行");sw.WriteLine("第二行");sw.Write("第三行");sw.WriteLine("第四行");
}

生成的 test.txt 文件內容為:

第一行第二行
第三行第四行

三、使用場景建議

  1. 逐行寫入文本(如日志、CSV):
    使用 WriteLine(),例如:

    sw.WriteLine("Name, Age");
    sw.WriteLine("Alice, 30");
    sw.WriteLine("Bob, 25");
    
  2. 格式化輸出(如拼接字符串):
    使用 Write() 配合 WriteLine(),例如:

    sw.Write("Total: ");
    sw.WriteLine(100.50); // 輸出:Total: 100.50
    
  3. 手動控制換行
    使用 Write() 并顯式添加換行符(\nEnvironment.NewLine),例如:

    sw.Write("第一部分內容\n"); // 等效于 sw.WriteLine("第一部分內容");
    sw.Write("第二部分內容" + Environment.NewLine); // 跨平臺換行符
    

四、性能差異
兩者的性能差異極小,可忽略不計。但在大量寫入時:

  • WriteLine() 可能略微慢于 Write()(多一次換行符寫入)。
  • 建議結合 BufferedStream 提升整體性能:
    using (FileStream fs = new FileStream("test.txt", FileMode.Create))
    using (BufferedStream bs = new BufferedStream(fs, 8192)) // 8KB 緩沖區
    using (StreamWriter sw = new StreamWriter(bs))
    {// 批量寫入
    }
    

五、注意事項

  1. 換行符的平臺差異

    • Windows 默認使用 \r\n(回車+換行)。
    • Linux/macOS 使用 \n(換行)。
    • WriteLine() 會根據當前操作系統自動選擇換行符(通過 Environment.NewLine)。
  2. Console.WriteLine() 的類比

    • StreamWriterWriteLine()Console.WriteLine() 邏輯一致,只是輸出目標不同(文件 vs 控制臺)。

六、總結

  • WriteLine():當需要每行獨立時(如日志、配置文件)。
  • Write():當需要自定義格式或拼接內容時(如 JSON、HTML)。
  • 混用:當需要靈活控制換行位置時(如表格輸出)。

合理選擇方法可以讓代碼更簡潔、輸出更易讀。

1.6、 StreamWriter.Close的作用

在 C# 中,sw.Close() 的作用是 釋放 StreamWriter 占用的系統資源(如文件句柄、網絡連接等)。如果不調用 Close(),會導致以下問題:

一、不調用 Close() 的后果

  1. 資源泄漏

    • 文件句柄不會立即釋放,其他程序無法訪問該文件(如無法刪除或修改)。
    • 若頻繁創建 StreamWriter 而不關閉,可能耗盡系統資源(如文件句柄上限)。
  2. 數據丟失風險

    • StreamWriter緩沖區(默認 4KB),數據會先寫入緩沖區,而非直接寫入文件。
    • 若不調用 Close()Flush(),緩沖區中的數據可能 不會被寫入文件
  3. 異常處理不完善

    • 若寫入過程中發生異常,Close() 可能不會被執行,導致資源無法釋放。

二、Close() 的底層邏輯
Close() 方法實際上做了兩件事:

  1. Flush():將緩沖區中的數據強制寫入文件。
  2. Dispose():釋放非托管資源(如文件句柄),并標記對象已銷毀。

三、推薦替代方案:using 語句
C# 提供了 using 語句,它會自動調用 Dispose() 方法(等價于 Close()),即使發生異常也能確保資源釋放。
示例對比

// 不使用 using(需手動 Close())
StreamWriter sw = new StreamWriter("test.txt");
sw.WriteLine("Hello");
sw.Close(); // 必須顯式調用,否則資源泄漏// 使用 using(自動釋放資源)
using (StreamWriter sw = new StreamWriter("test.txt"))
{sw.WriteLine("Hello");// 無需調用 Close(),using 塊結束時自動釋放
}

四、為什么示例代碼中不調用 Close() 仍“正常”?

  1. 程序退出時系統回收資源
    若程序立即退出,操作系統會強制釋放文件句柄,但這是不可控的行為,不推薦依賴。

  2. 緩沖區自動刷新

    • 緩沖區滿時(默認 4KB)會自動刷新。
    • 若寫入的數據量很小(如示例中的幾行文本),可能未填滿緩沖區,導致數據丟失。

五、最佳實踐

  1. 永遠使用 using 語句
    避免手動調用 Close(),讓 using 自動管理資源。

  2. 顯式調用 Flush()(可選)
    若需要立即寫入數據(如實時日志),可調用 Flush()

    using (StreamWriter sw = new StreamWriter("log.txt"))
    {sw.WriteLine("重要日志");sw.Flush(); // 立即寫入文件,不等待緩沖區滿
    }
    
  3. 處理大文件時增大緩沖區
    通過構造函數調整緩沖區大小(如 64KB),減少 IO 次數:

    using (FileStream fs = new FileStream("large.txt", FileMode.Create))
    using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8, 65536))
    {// 寫入大量數據
    }
    

六、總結

  • Close() 的作用:釋放資源并確保數據寫入文件。
  • 不調用的風險:資源泄漏、數據丟失。
  • 推薦方案:使用 using 語句替代手動 Close(),提升代碼安全性和簡潔性。

二、

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89488.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89488.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89488.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ctf.show-web習題-web2-最簡單的sql注入-flag獲取詳解、總結

解題思路打開靶場既然提示是最簡單的sql注入了,那么直接嘗試永真登錄1 or 11#這里閉合就是簡單的單引號可以看到沒登錄成功,但是有回顯:歡迎你,ctfshowsql注入最喜歡的就是回顯了!這題的思路就是靠這個回顯&#xff0c…

upload-labs 靶場通關(1-20)

目錄 Pass-01(JS 繞過) Pass-02(文件類型驗證) Pass-03(黑名單驗證) Pass-04(黑名單驗證.htaccess) Pass-05(大小寫繞過) Pass-06(末尾空格) Pass-07(增加一個.) Pass-08(增加一個::$DATA) Pass-09(代碼不嚴謹) Pass-10(PPHPHP&am…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+vue實現的酒店預訂管理系統,推薦!

摘 要 使用舊方法對酒店預訂信息進行系統化管理已經不再讓人們信賴了,把現在的網絡信息技術運用在酒店預訂信息的管理上面可以解決許多信息管理上面的難題,比如處理數據時間很長,數據存在錯誤不能及時糾正等問題。 這次開發的酒店預訂管理系…

LSTM入門案例(時間序列預測)| pytorch實現(可復現)

需求 假如我有一個時間序列,例如是前113天的價格數據(訓練集),然后我希望借此預測后30天的數據(測試集),實際上這143天的價格數據都已經有了。這里為了簡單,每一天的數據只有一個價…

Axure RP 10 預覽顯示“無標題文檔”的空白問題探索【護航版】

1. 安裝情況 官網 Axure RP 10:Download Axure RP 10 - Axure (PS:11都出了) 版本:10.0.0.3924 激活碼:49bb9513c40444b9bcc3ce49a7a022f9 (10/11都可以用,但只嘗試了10&#xff…

基于SpringBoot+Vue的汽車租賃系統(協同過濾算法、騰訊地圖API、支付寶沙盒支付、WebsSocket實時聊天、ECharts圖形化分析)

系統亮點:協同過濾算法、騰訊地圖API、支付寶沙盒支付、WebsSocket實時聊天、ECharts圖形化分析;01系統開發工具與環境搭建—前后端分離架構項目架構:B/S架構運行環境:win10/win11、jdk17前端:技術:框架Vue…

數據結構入門:像整理收納一樣簡單!

在我們生活中,經常會面對這樣的問題: “我要怎么整理我的衣柜?” “電腦里照片太多了,怎么歸類才方便查找?” 其實,程序員也有類似的煩惱。他們不整理衣柜,而是“整理數據”。而這門關于如何“收…

力扣每日一題--2025.7.15

📚 力扣每日一題–2025.7.15 3135. 有效單詞 (簡單) 大家好!今天我們要來聊聊一道有趣的編程題——有效單詞 📝 題目描述 題目分析 📚 題目要求我們判斷一個字符串是否為有效單詞。有效單詞需要滿足以下…

Mysql數據庫——增刪改查CRUD

文章目錄一、數據庫的基礎命令二、創建表三、增(create)四、查詢(retrieve)五、條件查詢(where)六、修改(update)七、刪除(delete)一、數據庫的基礎命令 1.使用客戶端連接服務器 mysql -u root…

關于pytorch虛擬環境及具體bug問題修改

本篇博客包含對于虛擬環境概念的講解和代碼實現過程中相關bug的解決關于虛擬環境我的pytorch虛擬環境在D盤,相應python解釋器也在D盤(一起),但是我的pycharm中的項目在C盤,使用的是pytorch的虛擬環境,這是為…

U盤量產工具與性能優化完全指南

本文還有配套的精品資源,點擊獲取 簡介:U盤量產工具是IT行業中的專業軟件,用于批量生產或修復U盤。安國和銀燦是兩個提供U盤量產工具的主控芯片制造商,提供初始化、格式化、分區管理、性能優化、故障修復、個性化定制、固件升級…

Golang http開發實戰:構建RESTful API保姆級教程

目錄 章節1:RESTful API的精髓與Go的Web開發哲學 RESTful API的設計原則 Go的http包核心組件 實戰:第一個RESTful API端點 章節2:設計優雅的RESTful路由 路由設計的注意事項 使用Gorilla Mux實現動態路由 章節3:請求與響應的藝術:解析與格式化 解析請求數據 統一…

UGUI 性能優化系列:第一篇——基礎優化與資源管理

UGUI 性能優化系列:第一篇——基礎優化與資源管理 UGUI 性能優化系列:第二篇——Canvas 與 UI 元素管理 在 Unity 游戲中,用戶界面(UI)是玩家與游戲交互的核心。然而,不當的 UGUI 使用常常成為游戲性能的…

多端協同的招聘系統源碼開發指南:小程序+APP一體化設計

當下,很多企業選擇搭建屬于自己的多端協同招聘平臺,尤其是中大型人力資源公司、連鎖品牌企業,以及同城服務平臺,更是將“小程序APP”一體化招聘系統視為提升效率、降低用工成本的利器。 今天,筆者將從源碼開發的角度&a…

Maven 配置文件核心配置:本地倉庫、鏡像與 JDK 版本

Maven 配置文件核心配置:本地倉庫、鏡像與 JDK 版本 在 Maven 項目開發中,合理配置 settings.xml 文件能顯著提升依賴管理效率。本文將聚焦本地倉庫、鏡像加速和 JDK 版本這三個核心配置,結合 IDEA 環境詳細講解配置方法與作用。 一、Maven 配…

【時時三省】(C語言基礎)通過指針引用字符串

山不在高,有仙則名。水不在深,有龍則靈。 ----CSDN 時時三省如在printf函數中輸出一個字符串。這些字符串都是以直接形式(字面形式)給出的,在一對雙撇號中包含若干個合法的字符。使用字符串的更加靈活方便的方法——通…

【Linux驅動-快速回顧】一文快速理解GIC內部寄存器對中斷的控制

第一部分:GIC的功能和組成 1. GIC要解決的根本問題 在一個復雜的片上系統(SoC)中,有非常多的硬件模塊(如定時器、串口、按鍵、DMA等),它們都需要在完成任務或遇到特定事件時通知CPU。同時&#…

【IoTDB 線上小課 17】開源 ≠ 免費,3 分鐘總結開源商用指南

【IoTDB 視頻小課】第十七期,解答你最關心的開源商業使用問題!關于 IoTDB,關于物聯網,關于時序數據庫,關于開源...一個問題重點,3-5 分鐘,我們講給你聽:原來開源商業化有這么多規則開…

VUE項目學習筆記 v-for綁定數據,該數據異步獲取,同時需要對v-for的DOM節點進行js操作

問題描述:項目里有一個輪播圖,輪播圖的圖片數據從服務器獲取,用v-for生成DOM在頁面中顯示,輪播圖插件會通過new Swiper給DOM添加CSS、事件等,實現輪播效果。在這里存在操作順序問題:當服務器返回圖片數據后…

Science | 如何利用“T細胞+組蛋白乙酰化”兩大國自然熱點?T細胞耗竭機制與代謝-表觀遺傳調控的新范式

CD8?T細胞耗竭(T cell exhaustion)是腫瘤免疫治療的核心瓶頸,其表觀遺傳重塑機制(如組蛋白修飾)是當前國自然重點資助的前沿方向。耗竭T細胞(TEX)是指在慢性感染(如持續性病毒感染&…