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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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)是指在慢性感染(如持续性病毒感染&…