StreamWriter与FileStream的关闭

问题描述

StreamWritersw=File.CreateText(path);//写入sw.Close();

当我们创建一个StreamWriter,使用完成后,直接关闭即可。但当我们先创建一个FileStream,在此基础上再创建一个StreamWriter,却需要先关闭StreamWriter,再关闭FileStream,如下:FileStreamfs=File.Open(path,FileMode.OpenOrCreate);StreamWritersw1=newStreamWriter(fs);//写入sw1.Close();fs.Close();

第二种方法需要先打开文件,再进行写操作。再关闭写的流,然后关闭文件流。而第一种方法只需要关闭写的流,难道它不需要打开和关闭文件吗?

解决方案

解决方案二:
第2种方式是用流去创建流,按照微软示例只需要关闭后者即可,但一般谨慎起见会加上前者的关闭,打开关闭成对也便于代码阅读。msdn示例:https://msdn.microsoft.com/zh-cn/library/wtbhzte9(v=vs.80).aspx
解决方案三:
所以说fs关闭后sw1并没有什么卵用其实流也就只有一个而已不是因为你创建了多少个类就有多少个流sw1只是继承的fs的流而已所以fs关闭后sw1就没有什么卵用了而且我一般也不使用你后面这种写法看着别扭using(StreamReaderreader=newStreamReader(path,Encoding.UTF8)){}

解决方案四:
首先这两种方法的Close函数是不一样的。StreamWriter并不是Stream的子类,它是一个封装好的类,功能是向流里面写入字符。因此它的close方法和Stream类是不一样的,当调用它的close函数的时候,它会是否自己占用的所有资源,包括流,所以。而第二种,则是关闭实例化了的Stream子类,也就是你说的关闭流。
解决方案五:
在StreamWriter类中包含一个私有的Stream,如果你使用publicStreamWriter(stringpath);这个构造函数,StreamWriter会主动创建一个FileStream如果你使用publicStreamWriter(Streamstream);这个构造函数,StreamWriter则不会再创建FileStream而是直接使用你传入的Stream。其次,无论你是使用的哪个构造函数,StreamWriter在Close的时候都会关闭FileStream。你可以尝试如下代码:FileStreamfs=newFileStream(@"D:test.txt",FileMode.OpenOrCreate);StreamWritersw=newStreamWriter(fs);sw.Close();fs.Close();在sw.Close();执行完毕后,其实fs已经被关闭了。因此fs.Close();其实是可以省略的。当然,这样的写法不会有任何问题,因为Dispose不会被执行两次。但是,sw.Close();fs.Close();这两行代码不可以交换顺序,如果先执行fs.Close();再执行sw.Close();将引发异常。因为在StreamWriter的Close函数调用过程中,将调用Flush函数,而此时fs已经被关闭,Flush将产生异常。如果想详细了解,可以查看StreamWriter的源代码。其实,在这种多重复用关系的对象中,都要遵循一个先创建,后关闭的原则。即先进后出,后进先出。就像栈一样。
解决方案六:
部分关键代码:internalStreamWriter(stringpath,boolappend,Encodingencoding,intbufferSize,boolcheckHost):base((IFormatProvider)null){if(path==null)thrownewArgumentNullException("path");if(encoding==null)thrownewArgumentNullException("encoding");if(path.Length==0)thrownewArgumentException(Environment.GetResourceString("Argument_EmptyPath"));if(bufferSize<=0)thrownewArgumentOutOfRangeException("bufferSize",Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));this.Init(StreamWriter.CreateFile(path,append,checkHost),encoding,bufferSize,false);}///<summary>///用指定的编码及默认缓冲区大小,为指定的流初始化<seecref="T:System.IO.StreamWriter"/>类的新实例,有选择性的打开流。///</summary>///<paramname="stream">要写入的流。</param><paramname="encoding">要使用的字符编码。</param><paramname="bufferSize">缓冲区大小(以字节为单位)。</param><paramname="leaveOpen">如果在释放<seecref="T:System.IO.StreamWriter"/>对象之后打开流对象,则为true;否则为,false。</param><exceptioncref="T:System.ArgumentNullException"><paramrefname="stream"/>或<paramrefname="encoding"/>为null。</exception><exceptioncref="T:System.ArgumentOutOfRangeException"><paramrefname="bufferSize"/>为负。</exception><exceptioncref="T:System.ArgumentException"><paramrefname="stream"/>不可写。</exception>[__DynamicallyInvokable]publicStreamWriter(Streamstream,Encodingencoding,intbufferSize,boolleaveOpen):base((IFormatProvider)null){if(stream==null||encoding==null)thrownewArgumentNullException(stream==null?"stream":"encoding");if(!stream.CanWrite)thrownewArgumentException(Environment.GetResourceString("Argument_StreamNotWritable"));if(bufferSize<=0)thrownewArgumentOutOfRangeException("bufferSize",Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));this.Init(stream,encoding,bufferSize,leaveOpen);}///<summary>///关闭当前的StreamWriter对象和基础流。///</summary>///<exceptioncref="T:System.Text.EncoderFallbackException">当前编码不支持显示半个Unicode代理项对。</exception><filterpriority>1</filterpriority>publicoverridevoidClose(){this.Dispose(true);GC.SuppressFinalize((object)this);}///<summary>///释放由<seecref="T:System.IO.StreamWriter"/>占用的非托管资源,还可以另外再释放托管资源。///</summary>///<paramname="disposing">true表示释放托管资源和非托管资源;false表示仅释放非托管资源。</param><exceptioncref="T:System.Text.EncoderFallbackException">当前编码不支持显示半个Unicode代理项对。</exception>[__DynamicallyInvokable]protectedoverridevoidDispose(booldisposing){try{if(this.stream==null||!disposing&&(!this.LeaveOpen||!(this.streamis__ConsoleStream)))return;this.CheckAsyncTaskInProgress();this.Flush(true,true);if(this.mdaHelper==null)return;GC.SuppressFinalize((object)this.mdaHelper);}finally{if(!this.LeaveOpen){if(this.stream!=null){try{if(disposing)this.stream.Close();}finally{this.stream=(Stream)null;this.byteBuffer=(byte[])null;this.charBuffer=(char[])null;this.encoding=(Encoding)null;this.encoder=(Encoder)null;this.charLen=0;base.Dispose(disposing);}}}}}
解决方案七:
是的!应该通过看源代码来学习.net。许多时候,源代码跟自己推理、眼睛看到的都有差别。写fs.Close()其实是多余的写法,只不过不会报错而已。大多数人都会有担心,所以写它也无妨,.net也支持你多余地写fs.Close()。然而从原理上看,StreamWriter在Close时会额外地去调用stream的Close方法。
解决方案八:
第二种你关闭fs都是多余的,请阅读StreamWriter.Close的作用
解决方案九:
StreamWriter执行Close的时候就会去执行Dispose,而执行Dispose的时候就会去执行Flush并且再将当初做为参数的stream也给Close了。但是为了简单,我们通常写using(FileStreamfs=File.Open(path,FileMode.OpenOrCreate))using(StreamWritersw1=newStreamWriter(fs)){.......使用sw1的操作};

这可以确保调用Dispose。不用调用Close,调用dispose就够了。如果不写,显然GC回收StreamWriter对象时也会调用Dispose的,也会去Flush和Close。但是那就有几秒钟延迟,而这个时候可能就会造成应用中某些地方的使用这些资源的代码抛出运行异常。而如果你显示地去使用using{}来调用Dispose,从上面贴出的源代码看,它调用了GC.SuppressFinalize((object)this),也就是说在GC回收StreamWriter对象时就不会额外去再调用Close方法了。

时间: 2024-07-29 20:56:39

StreamWriter与FileStream的关闭的相关文章

请问一个语法含义 using (FileStream fileStream = new FileStream(string, FileMode.Open, FileAccess.Read))

问题描述 闲来无事看到一段代码:using(FileStreamfileStream=newFileStream(string,FileMode.Open,FileAccess.Read,FileShare.Read)){XXXXXXXtry{}catch{}XXXXXXXXXXXXXXXXXXX}不知道这是什么语法现象,什么含义呢? 解决方案 解决方案二:filestream是类库system.io里的,所以用using引用实现的是:用filestream将读取文件信息到文件流里解决方案三:释

c# FileStream类读取文件

问题描述 c# FileStream类读取文件 FileStream aFile = File.OpenRead("Data.txt"); 为什么能创建对象? 解决方案 C# 读取txt文件 FileStream,StreamReader,StreamWriterc#FileStream文件读写C# FileStream文件读写 解决方案二: C# 读取txt文件 FileStream,StreamReader,StreamWriter c#FileStream文件读写 C# File

使用CLR会造成内存方面的问题吗

我老是担心使用CLR会造成内存方面的问题,比如内存不能回收.其实想一想也许我过滤了,毕竟.NET Framework能够自己回收托管内存.既然在应用服务器上能使用,数据库上似乎也可以使用. 希望听一听大家的经验和见解~~ Peak Wong: 一般不用, 主要是DBA管理这种东西的时候会很麻烦, 因为自己写的CLR很难保证没有BUG, 一旦出BUG, 如果只是影响调用那一部分还好, 如果导致整个服务挂掉, 则很危险了(而且往往导致服务器挂掉还不一定查得出来是否CLR的问题) 另外, 部署和迁移也

通过C#动态生成图书信息XML文件_实用技巧

通过C#动态生成图书信息XML文件(Books.xml),文件如下: 复制代码 代码如下: <?xml version="1.0" encoding="iso-8859-1"?> <bookstore> <book id="1" category="CHILDREN"> <title>Harry Potter</title> <author>J K. Ro

C#中应用PSFTP实现SFTP上传

上传 SFTP,第一次听说,还以为是公司自己搞得一个东东呢,google了一下,原来是一种FTP协议,是可信任的FTP,类似于HTTPS协议. 这次项目就是要将一些数据文件打包通过SFTP传到德国的Server,所以中途是需要加密传输的,即通过SFTP进行数据的上传动作. 找了一个开源的东东,PSFTP,是一个绿色EXE档,C#中控制也很方便,于是自己封装了一下方便自己的应用. PSFTP的命令是典型的Unix命令,很简单易懂 ,下面是其基本的命令: C#中使用Process调用该EXE实现FT

Step1数据系统技术(5.使用GZIP技术优化文件缓存)

在上面的一篇,我们讲到了服务器端的缓存,我的地名信息系统有70万个页面,生成该页面的过程需要我从远程的数据库加载5个SQL数据返回的内容,还有RSS格式的新闻,因此生成一个页面是很困难的,因此我使用了服务端缓存技术使性能获得了大幅的提升,不过,又遇到了新的关于硬盘空间和流量的问题. 网站的70万个地名当然不会一天之内都会被访问,不过我的网站该栏目日访问量大约为30000,考虑到重复的访问,假设只访问了10000个地名(实际上是不只的,因为地名的访问很零散),那就是会有10000个缓存文件被生成,

服务器发布IIS之后,.Net 程序读取不到Excel内容

问题描述 服务器发布IIS之后,.Net程序读取不到Excel内容具体问题:本地系统Windows732位,Oracle32位Office201032位,发布IIS之后可以正常操作.可是发布到客户服务器windowsserver2012r264位系统中,装Oracle64位,Office201032位,发布IIS后,浏览Excel文件之后,点击导入,可以把Excel文件保存到服务器的目录下,页面读取不到excel的内容?如下图:服务器路径下点击[导入]按钮之后上传的excel文件:通过代码弹出客

c#窗体-C#窗体程序中文件夹复制问题

问题描述 C#窗体程序中文件夹复制问题 想问一下,用什么可以把一个文件夹复制到另一个文件夹里面,我试过StreamReader.StreamWriter和FileStream.但是访问路径时被拒绝了,然后我有想过用Directory在目的文件夹里创建一个和源文件夹名称一样的文件夹,然后用File.Copy()把源文件夹里的文件一个个复制到目的文件夹里,结果不会用.所以向各位求助一下,谁能帮我一下,谢谢了! 解决方案 以管理员方式运行你的程序即可,你的代码没有问题.用不着StreamReader.

ASP.NET 文件断点续传实现代码_实用技巧

这里我通过Response类中的AddHeader方法将一个HTTP头添加到输出流中.在HTTP头中,是由头信息和体信息组成.两者之间用一行空行分开.这里利用在头中加入Range段,来表示客户端希望从何处继续下载,来实现续传功能. 好了废话不多说,让我们开始吧. 1.新建1个主页,名字随便起哈. 2.在该页中添加1个LinkButton按钮,该按钮用来执行实现的过程. 3.在LinkButton的Click事件中,实现断点续传功能. 代码如下: 另外不要忘记引用System.IO命名空间,这里只