2010-08-09 13 views
9

Tengo el siguiente método y, por algún motivo, la primera llamada a Copiar parece no hacer nada. Alguien sabe por qué? En la entrada al método está comprimido y base64 puede suministrar ese método si es necesario.¿Por qué necesito dos llamadas para transmitir CopyTo?

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

Respuesta

2

Si la primera llamada a Read() devuelve 0, Stream.CopyTo() tampoco funcionará. Si bien esto apunta a un problema con GZipStream, es muy poco probable que tenga un error como este. Mucho más probable es que algo salió mal cuando creó los datos comprimidos. Como comprimir primero 0 bytes, y luego comprimir los datos reales.

2

Sólo una conjetura, pero es porque el nuevo GZipStream constructor deja el índice al final de la matriz, y los primeros CopyTo restablece al inicio, de manera que cuando se llama a la segunda CopyTo su ahora en el inicio y copia los datos correctamente?

1

¿Qué tan seguro está de que la primera copia no hace nada y la segunda funciona , que sería un error en la clase GZipStream. Su código debería funcionar bien sin llamar a CopyTo dos veces.

+0

La primera copia no rellena la secuencia; obtener el mismo comportamiento con el método de lectura. El GZipStream es un tipo de clase de Microsoft, ¿no hay un error en su clase? –

+0

Hmm ¿estás 100% seguro? Leer es una cuestión completamente diferente, el contrato en el método de lectura dice que no se garantiza que devuelva la cantidad de bytes solicitados, pero la documentación de CopyTo no hace el mismo reclamo, pero quizás usa el método Read internamente. ¿Ha intentado usarlo en un ciclo ex por el ejemplo en la página Stream.Read MSDN http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx –

+0

Ya comenzó con un ciclo , la primera llamada para leer devuelve 0, llamadas posteriores para leer bytes de retorno hasta el final. –

0

Hola gracias por la contribución de todos. Resulta que el error fue causado por un error en el método de codificación. El método era

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

La línea de retorno debe ser inferior a la usando permitiendo que la corriente de compresión para cerrar y al ras, esto hizo que el comportamiento incoherente al descomprimir la corriente.

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

Gracias por la ayuda de todos.

Cuestiones relacionadas