【问题标题】:How to close a stream when it returns a stream返回流时如何关闭流
【发布时间】:2016-05-25 05:22:42
【问题描述】:
 public Stream DecryptFile(string inputFile)//, string outputFile)
    {
        {  
                string password = @"mykey"; // Your Key Here

                UnicodeEncoding UE = new UnicodeEncoding();
                byte[] key = UE.GetBytes(password);

                FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);

                RijndaelManaged RMCrypto = new RijndaelManaged();

                CryptoStream cs = new CryptoStream(fsCrypt,
                    RMCrypto.CreateDecryptor(key, key),
                    CryptoStreamMode.Read);


                StreamReader sr = new StreamReader(cs);



              Stream s = sr.BaseStream;
                //sr.Close();
                //fsCrypt.Close();
             return s;
        }
    }

在此代码中存在流未正确关闭的问题。 如果我在返回值之前关闭它,则会引发错误。

【问题讨论】:

  • 读取文件后它不允许我替换它,因为流是打开的。
  • 你需要在返回 s 之前关闭 fsCrypt
  • 如果我在它显示找不到表 0 之前关闭它。

标签: c# filestream


【解决方案1】:

应该执行fsCrypt.Close();,但不应该执行sr.Close();,因为函数的调用者应该能够使用Stream。

另外,为了在发生错误时正确关闭流,请使用一次性上下文:

using (FileStream fsCrypt = new FileStream(inputFile, FileMode.Open))
{
    RijndaelManaged RMCrypto = new RijndaelManaged();

    CryptoStream cs = new CryptoStream(fsCrypt,
        RMCrypto.CreateDecryptor(key, key),
        CryptoStreamMode.Read);

    StreamReader sr = new StreamReader(cs);
    Stream s = sr.BaseStream;
    return s;
}

调用者也应该使用这种模式:

using (var stream = DecryptFile(string inputFile))
{
    // do something with decrypted file
}

【讨论】:

  • 如果你说“一次性上下文”之类的东西,请解释一下,因为高级语言的新程序员不知道幕后实际发生了什么,或者为什么他们不需要去寻求结果堆栈和堆了。在您在该领域工作几年之前,使用并不是最简单的概念
  • 但是当我也关闭解密功能时,如上所述,它显示无法从关闭的文件中读取另一个问题。
【解决方案2】:
using (FileStream fs = new FileStream(filePath, FileMode.Open,     FileAccess.Read, FileShare.ReadWrite))
{

//code here
}

我认为它是在 .NET 3.0 左右引入的,您不再需要关闭流

使用方括号内的所有内容将在代码离开该部分时自动关闭并丢弃

【讨论】:

    【解决方案3】:

    使用 usings 来实现它可能会更好。 Usings 为您关闭并处理底层流。

    public Stream DecryptFile(string inputFile)//, string outputFile)
    {
        string password = @"mykey"; // Your Key Here
        UnicodeEncoding UE = new UnicodeEncoding();
        byte[] key = UE.GetBytes(password);
        using(var fsCrypt = new FileStream(inputFile, FileMode.Open)
        {
            RijndaelManaged RMCrypto = new RijndaelManaged();
            using(CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read))
            {
                StreamReader sr = new StreamReader(cs);
                Stream s = sr.BaseStream;
                return s;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 2019-10-01
      • 1970-01-01
      相关资源
      最近更新 更多