2010-08-09 9 views
9

J'ai la méthode suivante et pour une raison quelconque, le premier appel à copier semble ne rien faire? Quelqu'un sait pourquoi? En entrée de la méthode est compressée et base64 peut fournir cette méthode si nécessaire.Pourquoi ai-je besoin de deux appels pour diffuser 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(); 
     } 
    } 

Répondre

2

Si le premier appel à Read() renvoie 0 alors Stream.CopyTo() ne fonctionnera pas non plus. Bien que cela indique un problème avec GZipStream, il est très peu probable qu'il ait un bug comme celui-ci. Beaucoup plus probable est que quelque chose s'est mal passé lorsque vous avez créé les données compressées. Comme d'abord compresser 0 octets, puis compresser les données réelles.

2

Juste une supposition, mais est-ce parce que le nouveau GZipStream constructeur quitte l'indice à la fin du tableau, et les premiers CopyTo remet à zéro au début, de sorte que lorsque vous appelez la seconde CopyTo son maintenant le début et copie les données correctement?

1

Comment êtes-vous sûr que la première copie ne fait rien et la seconde fonctionne , ce serait un bogue dans la classe GZipStream. Votre code devrait fonctionner correctement sans appeler CopyTo deux fois.

+0

La première copie ne remplit pas le flux; obtenir le même comportement avec la méthode read. Le GZipStream est un Microsoft classe surly il n'y a pas une erreur dans la classe? –

+0

Hmm êtes-vous sûr à 100%. Read est une autre question entièrement le contrat sur la méthode de lecture dit qu'il n'est pas garanti de retourner la quantité d'octets demandés, mais la documentation CopyTo ne fait pas la même réclamation, mais peut-être utilise la méthode Read en interne. Avez-vous essayé de l'utiliser dans une boucle ex par l'exemple sur la page MSDN Stream.Read http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx –

+0

Ya a commencé avec une boucle , le premier appel à lire renvoie 0, les appels suivants à lire les octets de retour jusqu'à la fin. –

0

Salut merci pour la contribution de tout le monde. Il s'avère que l'erreur a été causée par une erreur dans la méthode d'encodage. La méthode était

/// <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 ligne de retour doit être inférieure à l'aide de flux permettant de compression pour fermer et chasse d'eau, cela a causé le comportement incohérent lorsque décompressé le cours d'eau.

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

Merci pour l'aide de tout le monde.