2009-10-15 6 views
2

Je travaille avec une composante 3ème partie qui retourne un objet IStream (System.Runtime.InteropServices.ComTypes.IStream). J'ai besoin de prendre les données dans ce IStream et l'écrire dans un fichier. J'ai réussi à faire cela, mais je ne suis pas vraiment content du code.Comment stocker un IStream dans un fichier via C#?

Avec « STRM » être mon IStream, voici mon code de test ...

// access the structure containing statistical info about the stream 
System.Runtime.InteropServices.ComTypes.STATSTG stat; 
strm.Stat(out stat, 0); 
System.IntPtr myPtr = (IntPtr)0; 

// get the "cbSize" member from the stat structure 
// this is the size (in bytes) of our stream. 
int strmSize = (int)stat.cbSize; // *** DANGEROUS *** (long to int cast) 
byte[] strmInfo = new byte[strmSize]; 
strm.Read(strmInfo, strmSize, myPtr); 

string outFile = @"c:\test.db3"; 
File.WriteAllBytes(outFile, strmInfo); 

À tout le moins, je ne l'aime pas longtemps int CAST a commenté ci-dessus, mais je me demande s'il y a pas une meilleure façon d'obtenir la longueur du flux d'origine que ce qui précède? Je suis un peu nouveau à C#, donc merci pour les pointeurs.

Répondre

3

Vous n'êtes pas obligé de le faire casting, comme vous pouvez lire les données à partir IStream la source en morceaux.

// ... 
System.IntPtr myPtr = (IntPtr)-1; 
using (FileStream fs = new FileStream(@"c:\test.db3", FileMode.OpenOrCreate)) 
{ 
    byte[] buffer = new byte[8192]; 
    while (myPtr.ToInt32() > 0) 
    { 
     strm.Read(buffer, buffer.Length, myPtr); 
     fs.Write(buffer, 0, myPtr.ToInt32()); 
    } 
} 

De cette façon (si les travaux) est plus efficace de la mémoire, car il utilise juste un petit bloc de mémoire pour transférer des données entre que les flux.

+0

vous a été plus rapide ... – Arthur

+1

Rubens - merci pour le code ci-dessus de l'échantillon. Cela clarifie définitivement certaines choses pour moi. Malheureusement, je n'ai pas été en mesure de tester cela depuis que je l'ai posté, et ne le sera pas un peu plus longtemps. À ce moment-là, je vais soit accepter cette réponse, soit poster pour plus de précisions si nécessaire. –

+0

okidoki, ty pour vos commentaires! –

1

System.Runtime.InteropServices.ComTypes.IStream est une enveloppe pour ISequentialStream.

De MSDN: http://msdn.microsoft.com/en-us/library/aa380011(VS.85).aspx

Le nombre réel d'octets lus peut être inférieur au nombre d'octets demandé si une erreur se produit ou si la fin du flux est atteinte pendant l'opération de lecture . Le nombre de octets renvoyés doit toujours être par rapport au nombre d'octets demandé. Si le nombre d'octets retourné est inférieur au nombre de octets demandés, cela signifie généralement la méthode de lecture a tenté de lire après la fin du flux.

Cette documentation indique que vous pouvez lire en boucle et lire tant que pcbRead est inférieur à cb.

+0

Arthur - merci pour le lien. Plus de documentation est toujours la bienvenue ... –

Questions connexes