簡體   English   中英

關閉FileStream會關閉StreamReader嗎?

[英]Will closing a FileStream close the StreamReader?

如果我使用FileStream創建StreamReader,關閉FileStream時StreamReader會關閉還是我還需要關閉StreamReader?

public void ReadFile()
{
    var file = new FileStream("c:\file.txt", FileMode.Open, FileAccess.Read);
    var reader = new StreamReader(file);

    try
    {
        txtFile.Text = reader.ReadToEnd();
    }
    catch (Exception)
    {
        throw;
    }
    finally
    {
        file.Close();
    }
}

基本上是的。 您實際上不必關閉StreamReader。 如果這樣做,它所做的就是關閉底層流。

@Bruno對關閉最外層包裝器提出了一個很好的觀點。 最好關閉最外層的流並讓它關閉底層流,以確保正確釋放所有資源。

來自Reflector ......

public class StreamReader : TextReader
{
    public override void Close()
    {
        this.Dispose(true);
    }

    protected override void Dispose(bool disposing)
    {
        try
        {
            if ((this.Closable && disposing) && (this.stream != null))
            {
                this.stream.Close();
            }
        }
        finally
        {
            if (this.Closable && (this.stream != null))
            {
                this.stream = null;
                this.encoding = null;
                this.decoder = null;
                this.byteBuffer = null;
                this.charBuffer = null;
                this.charPos = 0;
                this.charLen = 0;
                base.Dispose(disposing);
            }
        }
    }
}

不,你應該關閉reader 實際上,這可能不會出現任何問題,但StreamReader可能會增加一些可能需要清理的開銷。 所以你應該總是關閉最頂層的包裝器。

您也可以使用File.ReadAllText方法:

txtFile.Text = File.ReadAllText(@"c:\file.txt");

您不需要關閉StreamReader,因為它不擁有任何非托管資源。 關閉FileStream就足夠了。 你可以重寫代碼using這樣的:

public void ReadFile()
{
    using (var file = new FileStream("c:\file.txt", FileMode.Open, FileAccess.Read))
    {
        txtFile.Text = new StreamReader(file).ReadToEnd();
    }
}

一般情況下,如果您有疑問,最好是安全並在使用完畢后處理所有IDisposable對象。

public void ReadFile()
{
    using (FileStream file = new FileStream("c:\file.txt", FileMode.Open, FileAccess.Read))
    {
        using (StreamReader streamReader = new StreamReader(file))
        {
            txtFile.Text = streamReader.ReadToEnd();
        }
    }
}

不。最好的辦法是按照打開它們的相反順序關閉它們。

在我看來,整體做到這一點的最好方法是讓FileStream只關閉它自己。 它並不隱含地了解自身上層中存在的任何事物,因此它做任何會影響那些更高層的事情實際上是錯誤的。

話雖如此,更高級別的構造不應該公理地假設任何提供的底層圖層,或者如果他們這樣做,他們應該明確地這樣做:

1)如果是從現有的流創建,然后是更高級別的結構應該能夠被底層流的獨立封閉(實際上只是處置它分配給自己使用)的任何資源,或關閉包括底層流。 這些應該是兩個不同的函數調用,例如Close()和CloseSelf()(如果要以與現有代碼向后兼容的方式實現)。

2)如果它不是從現有流創建的(也就是說,構造函數必須創建底層流),那么關閉更高級別的構造也應該強制關閉基礎流,因為在這種情況下,底層流是高級構造的隱含部分。 在這種情況下,CloseSelf()只會調用Close()。

以它完成的方式實現這些類似乎很浪費。 如果您計划使用相同的文件(作為示例)串行輸入和串行輸出,如果您希望獲得對后代類的更高級功能的訪問,系統會強制您將其視為兩個不同的實體。 您可以選擇堅持較低級別的構造並自己實現更高級別的功能 - 有效地重新實現您已經存在的特殊版本的后代類。

如果按上述方式完成,典型功能將像現在一樣簡單實現,但對於更復雜的應用程序,可以保留在文件上放置單個鎖並在需要時根據需要重新使用它的功能。反對不得不放棄鎖和所有相關資源,然后立即重新分配它們 - 在沒有任何正當理由的情況下向系統添加開銷和內存碎片。

但在現有條件下,正確的事情是清楚的。 不能假定FileStream知道它成為其中任何對象的任何內容,因此您必須關閉最外層的封閉構造。 無論是否有任何方式,這都適用,正如Bruno等人所指出的那樣,並且由於它們給出的原因 - 兼容性。 假設是最丑陋的蟲子的曾祖父。

有趣的是,關閉StreamReader或writer會影響擁有的FileStream的讀/寫狀態。 這似乎意味着您不能使用StreamReader,然后使用相同的文件流使用StreamWriter。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM