C# 不使用Flush()关闭文件流

C# 不使用Flush()关闭文件流,c#,filestream,flush,C#,Filestream,Flush,我可以在不调用(C#)的情况下关闭文件流吗?我理解这一点,并首先调用Flush方法。MSDN不是100%清楚,但Jon Skeet说的是“Flush”,所以在关闭/处置之前先执行它。不会痛的,对吧 发件人: 之前写入缓冲区的任何数据都会在 文件流已关闭,因此无需在之前调用Flush 调用Close。在调用Close后,对文件执行任何操作 流可能引发异常。在调用Close一次后,它 如果再次调用,则不会执行任何操作 处置不那么清楚: 此方法通过将任何更改写入备份来处理流 存储并关闭流以释放资源 备

我可以在不调用(C#)的情况下关闭文件流吗?我理解这一点,并首先调用
Flush
方法。

MSDN不是100%清楚,但Jon Skeet说的是“Flush”,所以在关闭/处置之前先执行它。不会痛的,对吧

发件人:

之前写入缓冲区的任何数据都会在 文件流已关闭,因此无需在之前调用Flush 调用Close。在调用Close后,对文件执行任何操作 流可能引发异常。在调用Close一次后,它 如果再次调用,则不会执行任何操作

处置不那么清楚:

此方法通过将任何更改写入备份来处理流 存储并关闭流以释放资源

备注:评论员可能是对的,这不是百分之百的清楚:

覆盖实现缓冲区的流上的刷新。使用此方法 将任何信息从基础缓冲区移动到其目标, 清除缓冲区,或同时清除两者。根据对象的状态,您可以 可能必须修改流中的当前位置(例如 例如,如果基础流支持查找)。额外的 信息请参见CanSeek

使用StreamWriter或BinaryWriter类时,不要刷新 基本流对象。而是使用类的Flush或Close方法, 这确保数据被刷新到底层流 首先,然后写入文件

测验: 我能说什么。。。所有文件都有文本-也许这只是数据太少

测试2
再一次-每个文件都有自己的字节。。。在我看来,它就像我从MSDN上读到的那样:在处理之前调用Flush或Close并不重要。。。有什么想法吗?

既然您已经说过,如果用户代码没有显式调用close&dispose,那么close&dispose会调用flush方法,那么我相信(在不使用flush的情况下关闭),如果有必要,您实际上希望能够放弃对
文件流所做的更改

如果这是正确的,那么单独使用
FileStream
是没有帮助的。您需要将此文件加载到
MemoryStream
(或数组,具体取决于您修改其内容的方式),然后在完成后决定是否保存更改

显然,这其中的一个问题是文件大小
FileStream
使用大小有限的写缓冲区来加速操作,但一旦耗尽,就需要刷新更改。由于.NET内存限制,如果需要完全保存较小的文件,则只能在内存中加载这些文件


一个更简单的替代方法是制作一个磁盘来复制文件,并使用普通的
FileStream
来处理它。完成后,如果需要放弃更改,只需删除临时文件,否则用修改过的副本替换原始文件。

文件流
包装在
缓冲流
中,并在缓冲流之前关闭文件流

var fs = new FileStream(...);
var bs = new BufferedStream(fs, buffersize);

bs.Write(datatosend, 0, length);

fs.Close();
try {
    bs.Close();
}
catch (IOException) {
}

我认为使用简单的using语句是安全的,它在调用GetBytes()之后关闭流

public static byte[] GetBytes(string fileName)
{
    byte[] buffer = new byte[4096];
    using (FileStream fs = new FileStream(fileName)) 
    using (MemoryStream ms = new MemoryStream())
    {
        fs.BlockCopy(ms, buffer, 4096); // extension method for the Stream class
        fs.Close();
        return ms.ToByteArray();
    }
}

我一直在跟踪一个新引入的错误,该错误似乎表明.NET 4在处理流时无法可靠地刷新对磁盘的更改(与.NET 2.0和3.5不同,后者总是可靠地刷新更改)

.NET4文件流类在.NET4中进行了大量修改,虽然重写了Flush*()方法,但似乎忘记了对.Dispose()的类似注意

这会导致文件不完整。

在大循环中使用Flush()是值得的。 当你必须在一个循环中读写一个大文件时。在另一种情况下,缓冲区或计算机足够大,在关闭()之前不进行一次刷新()并不重要

示例:您必须读取一个大文件(一种格式)并将其写入.txt

 StreamWriter sw =  ....    // using StreamWriter
// you read the File  ...
// and now you want to write each line for this big File using WriteLine ();


for ( .....)    // this is a big Loop because the File is big and has many Lines

{

 sw.WriteLine ( *whatever i read* );  //we write here somrewhere ex. one .txt anywhere

 sw.Flush();  // each time the sw.flush() is called, the sw.WriteLine is executed

}

sw.Close();
在这里,使用Flush()非常重要;否则,每个writeLine都保存在缓冲区中,直到缓冲区为frull或程序到达sw.close()时才写入

我希望这有助于理解Flush的功能,您不必在
Close()/Dispose()
上调用
Flush()
FileStream
将为您完成这项工作,您可以从其源代码中看到:

[System.Security.SecuritySafeCritical]//自动生成
受保护的覆盖无效处置(布尔处置)
{
//根据我们是否成功,不会有任何不同的做法
//处置与终结。这是利用
//正常可终结对象和关键对象之间的弱排序
//可终结对象,我将其包含在SafeHandle中
//针对FileStream的设计,当
//最后定稿。
试一试{
if(_handle!=null&&!_handle.IsClosed){
//在写入时将数据刷新到磁盘。之后
//考虑到这一点,我们也不需要冲洗
//我们的读取位置,无论手柄
//已向用户公开。他们可能不会
//希望我们这样做。
如果(_writePos>0){

FlushWrite(!disposing);//“复制到文件”-这不正是Flush所做的吗?我将其理解为未调用
Flush()
,但缓冲区会被刷新。按照我的理解,不刷新就无法关闭它。即使您没有显式调用它,它们也会为您刷新。是的-您可以调用
close()
不调用
Flush()
,但你不能在不刷新的情况下关闭:)好的-我想伟大的乔恩会知道的…我会更改阅读障碍牙医的帖子:关闭前刷新。你为什么要这样做?如果你不刷新,你不知道文件中有什么,什么不知道-所以你要关闭它
public static byte[] GetBytes(string fileName)
{
    byte[] buffer = new byte[4096];
    using (FileStream fs = new FileStream(fileName)) 
    using (MemoryStream ms = new MemoryStream())
    {
        fs.BlockCopy(ms, buffer, 4096); // extension method for the Stream class
        fs.Close();
        return ms.ToByteArray();
    }
}
 StreamWriter sw =  ....    // using StreamWriter
// you read the File  ...
// and now you want to write each line for this big File using WriteLine ();


for ( .....)    // this is a big Loop because the File is big and has many Lines

{

 sw.WriteLine ( *whatever i read* );  //we write here somrewhere ex. one .txt anywhere

 sw.Flush();  // each time the sw.flush() is called, the sw.WriteLine is executed

}

sw.Close();
    [System.Security.SecuritySafeCritical]  // auto-generated
    protected override void Dispose(bool disposing)
    {
        // Nothing will be done differently based on whether we are 
        // disposing vs. finalizing.  This is taking advantage of the
        // weak ordering between normal finalizable objects & critical
        // finalizable objects, which I included in the SafeHandle 
        // design for FileStream, which would often "just work" when 
        // finalized.
        try {
            if (_handle != null && !_handle.IsClosed) {
                // Flush data to disk iff we were writing.  After 
                // thinking about this, we also don't need to flush
                // our read position, regardless of whether the handle
                // was exposed to the user.  They probably would NOT 
                // want us to do this.
                if (_writePos > 0) {
                    FlushWrite(!disposing); // <- Note this
                }
            }
        }
        finally {
            if (_handle != null && !_handle.IsClosed)
                _handle.Dispose();

            _canRead = false;
            _canWrite = false;
            _canSeek = false;
            // Don't set the buffer to null, to avoid a NullReferenceException
            // when users have a race condition in their code (ie, they call
            // Close when calling another method on Stream like Read).
            //_buffer = null;
            base.Dispose(disposing);
        }
    }