Зачем мне два вызова для потоковой передачи CopyTo? - PullRequest
9 голосов
/ 09 августа 2010

У меня есть следующий метод, и по какой-то причине первый вызов функции 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();
        }
    }

Ответы [ 4 ]

2 голосов
/ 09 августа 2010

Если первый вызов Read () возвращает 0, то Stream.CopyTo () также не будет работать.Хотя это указывает на проблему с GZipStream, очень маловероятно, что в будет такая ошибка.Гораздо более вероятно, что что-то пошло не так, когда вы создали сжатые данные.Как сначала сжимать 0 байтов, а затем сжимать реальные данные.

2 голосов
/ 09 августа 2010

Просто предположение, но это потому, что новый конструктор GZipStream оставляет индекс в конце массива, а первый CopyTo сбрасывает его в начало, поэтому при вызове второго CopyTo его теперь на старте и правильно копирует данные?

1 голос
/ 09 августа 2010

Насколько вы уверены, что первая копия ничего не делает, а вторая работает, это будет ошибкой в ​​классе GZipStream.Ваш код должен нормально работать, не вызывая CopyTo дважды.

0 голосов
/ 10 августа 2010

Привет, спасибо всем за участие.Оказывается, ошибка была вызвана ошибкой в ​​методе кодирования.Метод был

  /// <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());
            }
        }
    }

. Обратная линия должна быть ниже, чем использование, позволяющее потоку сжатия закрываться и сбрасываться, это вызывало противоречивое поведение при распаковке потока.

        /// <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());
        }
    }

Спасибо за помощь всем.

...