2017-04-10 3 views
0

J'ai ci-dessous le code:sortie MemoryStream dans un fichier C#

string fileName = GetFileName(); 
using (var stream = new MemoryStream()) 
{ 
    using (var sw = new StreamWriter(stream)) 
    {    
     for (int i = 0; i < 20; i++) 
     { 
      sw.WriteLine(String.Format("{0};{1};{2};{3};{4};{5}", i.ToString(), (i*2).ToString(), "-_-_-", "-_" + i.ToString() + "_-", "3", "15")); 
     } 

     // Check if compression needed. 
     if (stream.Length > limit) 
     { 
      sw.Flush(); 
      stream.Position = 0; 

      using (Ionic.Zip.ZipFile zipFile = new Ionic.Zip.ZipFile()) 
      { 
       absoluteFileName = Path.GetFileName(fileName); 
       zipFile.AddEntry(absoluteFileName, stream); 

       zipFileName = Path.Combine(Path.GetDirectoryName(fileName), Path.ChangeExtension(absoluteFileName, ZipExtension)); 
       zipFile.Save(zipFileName); 
      } 
     } 
     else 
     { 
      // no compression needed 
      using (FileStream file = new FileStream(fileName, FileMode.Create, System.IO.FileAccess.Write)) 
      { 
       byte[] bytes = new byte[stream.Length]; 
       stream.Read(bytes, 0, (int)stream.Length); 
       file.Write(bytes, 0, bytes.Length); 
       //stream.Close(); 
      } 
     } 
    } 

Je suis en train de générer un fichier texte brut en cas longueur MemoryStream (en octets) ne dépasse pas une quantité de béton d'octets (limite (voir conditionnelle).

Si la longueur MemoryStream est supérieure à une quantité de béton d'octets puis-je créer un fichier compressé.

Mon problème est dans le corps d'autre lorsque je tente d'écrire tout le contenu du flux mémoire dans un fichier texte brut lorsqu'il n'est pas nécessaire de compresser (stream.Length < = limite). Je reçois un fichier de 39bytes mais quand je l'ouvre, il est vide, seulement de nouvelles lignes à l'intérieur.

Je le fais parce que je ne veux pas créer le fichier directement sur le disque au cas où je devrais le compresser. Donc, si à la fin pas besoin de compresser, j'écris tous les streammemory dans un fichier et c'est le problème, le fichier est vide, seulement les nouvelles lignes.

Qu'est-ce que je fais mal?

MAJ2 J'ai mis ci-dessous ligne juste avant conditionnelle:

sw.Flush(); 
stream.Position = 0; 

Et maintenant, le contenu est écrit dans le fichier.

+3

S'il vous plaît mettre plus d'effort dans le formatage de votre code dans l'avenir. Je l'ai fait pour vous cette fois, mais il est de votre responsabilité de rendre le code aussi lisible que possible. Utilisez l'aperçu et demandez-vous si c'est vraiment comme cela que vous voulez lire le code. –

+0

@JonSkeet ok, merci. – user1624552

+4

Où est 'stream.Position = 0;' dans la branche 'else'? –

Répondre

3

Mon problème est dans le corps else

Eh bien vous manipulez que d'une manière différente dans le premier corps if.

Dans le premier corps if, vous êtes chasse explicitement l'écrivain et rembobiner le flux:

sw.Flush(); 
stream.Position = 0; 

Vous ne faites pas non plus de ceux dans le corps else, donc vous ne serez pas les données cela a déjà été écrit dans le flux (pas de rembobinage) et il peut toujours y avoir des données tamponnées dans le StreamWriter (pas de vidage). C'est un problème.

Ensuite, vous vérifiez votre « limite » sans rinçage du StreamWriter, ce qui signifie qu'il pourrait y avoir un tas d'autres données qui signifie que vous devriez compress, mais vous n'êtes pas. Donc, je suggère que vous appelez sw.Flush() avant votre déclaration if se produit du tout.

Enfin, je recommande fortement contre la création d'un autre tableau d'octets pour aucune raison - le corps de votre déclaration using final peut être juste:

stream.CopyTo(file); 
+0

Aucune méthode CopyTo apparaît sur le flux, j'utilise .NET Framework 3.5 sous Visual Studio 2008. Il est uniquement disponible à partir de .NET Framework 4.0 et versions ultérieures. – user1624552

+0

@ user1624552: Cela aurait été utile si vous aviez dit que - je pense qu'il est raisonnable que la plupart des gens supposent que vous n'êtes pas contraint à un framework publié il y a près de 10 ans ... vous n'avez pas besoin de créer un autre octet tableau bien. Vous pouvez utiliser 'MemoryStream.GetBuffer()' à la place, par exemple. –

+0

Je suis d'accord, très désolé. Et merci beaucoup, vous sauvez ma journée! – user1624552