【问题标题】:How create FileStream but not save?如何创建 FileStream 但不保存?
【发布时间】:2010-12-23 03:55:03
【问题描述】:

我有代码功能

public static void DecryptFile(string inFile, string outFile, string password)
{
    // create and open the file streams
    using (FileStream fin = File.OpenRead(inFile),
              fout = File.OpenWrite(outFile))
    {
        int size = (int)fin.Length; // the size of the file for progress notification
        byte[] bytes = new byte[BUFFER_SIZE]; // byte buffer
        int read = -1; // the amount of bytes read from the stream
        int value = 0;
        int outValue = 0; // the amount of bytes written out

        // read off the IV and Salt
        byte[] IV = new byte[16];
        fin.Read(IV, 0, 16);
        byte[] salt = new byte[16];
        fin.Read(salt, 0, 16);

        // create the crypting stream
        SymmetricAlgorithm sma = CryptoHelp.CreateRijndael(password, salt);
        sma.IV = IV;

        value = 32; // the value for the progress
        long lSize = -1; // the size stored in the input stream

        // create the hashing object, so that we can verify the file
        HashAlgorithm hasher = SHA256.Create();

        // create the cryptostreams that will process the file
        using (CryptoStream cin = new CryptoStream(fin, sma.CreateDecryptor(), CryptoStreamMode.Read),
                  chash = new CryptoStream(Stream.Null, hasher, CryptoStreamMode.Write))
        {
            // read size from file
            BinaryReader br = new BinaryReader(cin);
            lSize = br.ReadInt64();
            ulong tag = br.ReadUInt64();

            if (FC_TAG != tag)
                throw new CryptoHelpException("File Corrupted!");

            //determine number of reads to process on the file
            long numReads = lSize / BUFFER_SIZE;

            // determine what is left of the file, after numReads
            long slack = (long)lSize % BUFFER_SIZE;

            // read the buffer_sized chunks
            for (int i = 0; i < numReads; ++i)
            {
                read = cin.Read(bytes, 0, bytes.Length);
                fout.Write(bytes, 0, read);
                chash.Write(bytes, 0, read);
                value += read;
                outValue += read;
            }

            // now read the slack
            if (slack > 0)
            {
                read = cin.Read(bytes, 0, (int)slack);
                fout.Write(bytes, 0, read);
                chash.Write(bytes, 0, read);
                value += read;
                outValue += read;
            }
            // flush and close the hashing stream
            chash.Flush();
            chash.Close();

            // flush and close the output file
            fout.Flush();
            fout.Close();

            // read the current hash value
            byte[] curHash = hasher.Hash;

            // get and compare the current and old hash values
            byte[] oldHash = new byte[hasher.HashSize / 8];
            read = cin.Read(oldHash, 0, oldHash.Length);
            if ((oldHash.Length != read) || (!CheckByteArrays(oldHash, curHash)))
                throw new CryptoHelpException("File Corrupted!");
        }

        // make sure the written and stored size are equal
        if (outValue != lSize)
            throw new CryptoHelpException("File Sizes don't match!");
    }
}

我需要返回 FileStream (fout) 并且 fout 不保存到硬盘

更新:

是的,MemoryStream 很好。但是我需要使用 FileStream 否则会发生错误:

不工作:

using (ZipInputStream s = new ZipInputStream(fout))
{

  ZipEntry theEntry;
  while ((theEntry = s.GetNextEntry()) != null)//exception

正在工作:

using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFile)))
{

  ZipEntry theEntry;
  while ((theEntry = s.GetNextEntry()) != null)

我需要解密文件,解压缩,然后仍然得到文本而不保存

【问题讨论】:

  • 如果您不想将FileStream 保存到磁盘,为什么还要创建它? FileStream 是磁盘文件的流视图。您可能想要其他类型的流吗?也许MemoryStream 是您正在寻找的?
  • @Jim Mischel,但是...我编辑帖子。
  • 不使用FileStream时会出现什么异常?
  • 无法访问私有流。
  • 如果 fout 未关闭异常将是“标题中的 EOF”。 ZipInputStream s - 不初始化

标签: c# filestream


【解决方案1】:

不要使用第二个FileStream。您可以改用MemoryStream

using (FileStream fin = File.OpenRead(inFile))
  using(Stream fout = new MemoryStream())
...

【讨论】:

  • @Brian - 既然您需要从调用函数访问流,为什么不从函数中简单地 return 它,而不是使用 void功能?
  • @Oded:我不明白你的建议。调用者已经知道流在哪里,因为调用者传入了 Stream 对象,outstream。 Outstream 可能是 FileStreamMemoryStream 或其他,但 调用者 创建了它。
  • @Brian - 我可以看到该函数将 3 个字符串作为输入,并从中创建了一些流,但调用者没有创建您的 fout 流。
  • @Oded:在 Denis 当前的代码中,调用者不会创建 fout 流。我的建议是调用者确实创建 fout 流(可能是也可能不是FileStream)。因此,我在回答中声明,“这留下了与调用者创建Stream 的责任。”
【解决方案2】:

我建议将您的方法签名更改为:

public static void DecryptFile(string inFile, string password, Stream outStream)

public static void DecryptFile(string inFile, string password, string outFile)

(只需使用FileStream 参数调用第一个即可非常轻松地实现第二个)。

这留下了由调用者创建Stream 的责任,与Oded 的解决方案相比,它的优势在于它不必将整个输出存储在内存中;用户可以选择提供Stream,它会在提供时使用输出。如果要解密的文件特别大,这可能很重要。

【讨论】:

  • 谢谢。我明白了。我改变了消息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-03
  • 1970-01-01
相关资源
最近更新 更多