【问题标题】:Why do I need two calls to stream CopyTo?为什么我需要两次调用才能流式传输 CopyTo?
【发布时间】:2010-08-09 12:41:26
【问题描述】:

我有以下方法,出于某种原因,第一次调用 Copy to 似乎什么也没做?有谁知道为什么? 该方法的输入被压缩,如果需要,base64 可以提供该方法。

private byte[] GetFileChunk(string base64)
    {
        using (
            MemoryStream compressedData = new MemoryStream(Convert.FromBase64String(base64), false),
            uncompressedData = new MemoryStream())
        {

            using (GZipStream compressionStream = new GZipStream(compressedData, CompressionMode.Decompress))
            {
                // first copy does nothing ?? second works
                compressionStream.CopyTo(uncompressedData);
                compressionStream.CopyTo(uncompressedData);
            }

            return uncompressedData.ToArray();
        }
    }

【问题讨论】:

    标签: c# c#-4.0 stream


    【解决方案1】:

    如果第一次调用 Read() 返回 0,那么 Stream.CopyTo() 也不会工作。虽然这表明 GZipStream 存在问题,但它非常不太可能存在这样的错误。当您创建压缩数据时,更有可能出现问题。就像先压缩0字节,再压缩真实数据。

    【讨论】:

      【解决方案2】:

      只是一个猜测,但这是因为新的 GZipStream 构造函数将索引留在数组的末尾,而第一个 CopyTo 将其重置为开头,因此当您调用第二个 CopyTo 时,它现在开始并正确复制数据?

      【讨论】:

        【解决方案3】:

        你有多确定第一个副本什么都不做而第二个有效 ,这将是GZipStream 类中的错误。您的代码应该可以正常工作而无需两次调用 CopyTo。

        【讨论】:

        • 第一个副本不填充流;使用 read 方法获得相同的行为。 GZipStream 是 Microsoft 类 surly 那里没有错误?
        • 嗯,你 100% 确定。 Read 完全是另一回事,read 方法的合同说它不能保证返回请求的字节数,但 CopyTo 文档没有做出相同的声明,但它可能在内部使用 Read 方法。您是否尝试按照 Stream.Read MSDN 页面 msdn.microsoft.com/en-us/library/system.io.stream.read.aspx 上的示例在循环中使用它
        • 你从一个循环开始,第一次调用 read 返回 0,随后调用 read 返回字节直到结束。
        • 正如我所说,这是 Read 的预期行为,它记录在链接的 MSDN 文章中,但是 CopyTo 不应该像这样,或者至少文档中没有任何内容表明它应该.
        【解决方案4】:

        您好,感谢大家的意见。事实证明,该错误是由编码方法错误引起的。方法是

          /// <summary>
            /// Compress file data and then base64s the compressed data for safe transportation in XML.
            /// </summary>
            /// <returns>Base64 string of file chunk</returns>
            private string GetFileChunk()
            {
                // MemoryStream for compression  output
                using (MemoryStream compressed = new MemoryStream())
                {
                    using (GZipStream zip = new GZipStream(compressed, CompressionMode.Compress))
                    {
        
                        // read chunk from file
                        byte[] plaintext = new byte[this.readSize];
                        int read = this.file.Read(plaintext, 0, plaintext.Length);
        
                        // write chunk to compreesion
                        zip.Write(plaintext, 0, read);
                        plaintext = null;
        
                        // Base64 compressed data
                        return Convert.ToBase64String(compressed.ToArray());
                    }
                }
            }
        

        返回线应低于 using 允许压缩流关闭和刷新,这会导致解压流时出现不一致的行为。

                /// <summary>
            /// Compress file data and then base64s the compressed data for safe transportation in XML.
            /// </summary>
            /// <returns>Base64 string of file chunk</returns>
            private string GetFileChunk()
            {
                // MemoryStream for compression  output
                using (MemoryStream compressed = new MemoryStream())
                {
                    using (GZipStream zip = new GZipStream(compressed, CompressionMode.Compress))
                    {
        
                        // read chunk from file
                        byte[] plaintext = new byte[this.readSize];
                        int read = this.file.Read(plaintext, 0, plaintext.Length);
        
                        // write chunk to compreesion
                        zip.Write(plaintext, 0, read);
                        plaintext = null;
                    }
        
                    // Base64 compressed data
                    return Convert.ToBase64String(compressed.ToArray());
                }
            }
        

        感谢大家的帮助。

        【讨论】:

          猜你喜欢
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          • 2020-11-23
          • 1970-01-01
          • 1970-01-01
          • 2019-08-07
          • 2021-01-14
          • 2018-02-01
          相关资源
          最近更新 更多