2009-05-05 5 views
4

C#/.NET 2.0.Détermination de la taille d'un fichier futur alors que les données sont encore en mémoire

J'ai donc une chaîne qui contient le contenu futur d'un fichier XML. Il contient des métadonnées et des données binaires provenant de fichiers image. Je voudrais en quelque sorte déterminer la taille du fichier XML une fois que j'écrirai les données de la chaîne dans le système de fichiers.

J'ai essayé ce qui suit et ni travaux:

Console.Out.WriteLine("Size: " + data.Length/1024 + "KB"); 

et

Console.Out.WriteLine("Size: " + (data.Length * sizeof(char))/1024 + "KB"); 

Ni œuvres (la taille réelle du fichier résultant dévie de ce qui est de retour de l'une de ces méthodes) . Il me manque évidemment quelque chose ici. Toute aide serait appréciée.

sérialisation XML:

// doc is an XMLDocument that I've built previously 
StringWriter sw = new StringWriter(); 
doc.Save(sw); 
string XMLAsString = sw.ToString(); 

écriture dans le fichier système (XMLAsString transmis à cette fonction de variables données nominatives):

Random rnd = new Random(DateTime.Now.Millisecond);  
FileStream fs = File.Open(@"C:\testout" + rnd.Next(1000).ToString() + ".txt", FileMode.OpenOrCreate); 
StreamWriter sw = new StreamWriter(fs); 
app.Diagnostics.Write("Size of XML: " + (data.Length * sizeof(char))/1024 + "KB"); 
sw.Write(data); 
sw.Close(); 
fs.Close(); 

Merci

+0

Comment faites-vous votre sérialisation xml? –

+0

La première chose que je ferais est de diviser par 1024 au lieu de 1000. Cela devrait aider avec la taille de kb. – JFV

+0

Comment écrivez-vous des données sur le système de fichiers? –

Répondre

9

Il vous manque le fonctionnement du processus de codage. Essayez ceci:

string data = "this is what I'm writing"; 
byte[] mybytes = System.Text.Encoding.UTF8.GetBytes(data); 

La taille du tableau est exactement le nombre d'octets qu'il doit prendre sur le disque si elle est en cours d'écriture d'une manière un peu « normal », comme UTF8 est l'encodage par défaut pour la sortie de texte (Je pense). Il peut y avoir un caractère EOF (End Of File) supplémentaire écrit ou non, mais vous devriez être très proche avec ça.

Edit: Je pense que ça vaut pour tout le monde de se rappeler que les caractères en C#/NET sont pas un octet, mais deux, et sont des caractères unicode, qui sont ensuite encodées à quels que soient les besoins de format de sortie.. C'est pourquoi toute approche avec data.Length*sizeof(char) ne fonctionnerait pas.

+0

Merci. Cela a fonctionné parfaitement. – cakeforcerberus

+0

Oh, et FYI, vous avez raison en ce que cela renvoie une valeur très légèrement sous ce qui se termine finalement sur le FS. =) Merci encore. – cakeforcerberus

1

En NTFS, si votre système de fichiers est configuré pour compresser, le fichier final peut être plus petit que ce que votre fichier réel pourrait être. Est-ce votre problème?

+0

Intéressant. Oui, la valeur renvoyée par les méthodes est toujours supérieure à la taille réelle sur le système de fichiers. – cakeforcerberus

+0

Pour autant que je sache, je n'ai pas l'option de compression définie cependant. – cakeforcerberus

0

Qu'est-ce que data dans votre exemple ci-dessus? Comment les données binaires sont-elles représentées dans le fichier xml?

Il est fort probable que vous souhaitiez effectuer une sérialisation complète dans un tableau d'octets pour obtenir une estimation précise de la taille. Le sérialiseur peut faire des choses arbitraires comme ajouter des balises CDATA et si pour une raison quelconque vous devez enregistrer le fichier en UTF-16 au lieu de UTF-8, eh bien cela va doubler votre taille là-bas probablement.

0

Vous pouvez enregistrer (ou écrire) dans un flux de mémoire puis déterminer la taille de ce flux de mémoire, c'est le seul moyen de déterminer la taille réelle sans l'écrire sur le disque.

Vous ne pouvez pas voir qu'il y a un quelconque intérêt à cela, vous pouvez aussi bien enregistrer un fichier local, jeter un oeil à la taille finale du fichier, puis faire un choix quant à ce qu'il faut faire avec.Si tout ce que vous voulez faire est de faire une estimation raisonnable de la taille d'un fichier XML va devenir une fois que vous avez ajouté un tas d'éléments binaires codés et si nous pouvons supposer que le reste du XML sera négligeable en comparaison au contenu binaire codé, alors il s'agit de déterminer la météorisation introduite en raison de l'encodage. Typiquement, nous encoderions un contenu binaire avec un codage en base64, ce qui donne 4 octets d'ASCII pour 3 octets de binaire, c'est-à-dire un ballonnement de 33%. Donc, une estimation serait data.Length * 1.33333

1

Si vous voulez déterminer si votre fichier tiendra sur le média, vous devez prendre en compte la taille d'allocation du système de fichiers. Un fichier de 10 octets n'occupe pas 10 octets sur le disque. L'espace requis augmente en étapes discrètes, déterminées par la taille d'allocation (également appelée taille de cluster).

Voir this Microsoft support article pour plus d'informations sur les tailles de cluster NTFS et FAT.

Questions connexes