C# 在数据仍在内存中时确定未来文件的大小

C# 在数据仍在内存中时确定未来文件的大小,c#,C#,这是C#/.NET2.0 所以我有一个字符串,它包含XML文件的未来内容。它包含来自图像文件的元数据和二进制数据。我希望在将字符串中的数据写入文件系统后,以某种方式确定XML文件的大小 我尝试了以下方法,但两种方法都无效: Console.Out.WriteLine("Size: " + data.Length/1024 + "KB"); 及 两者都不起作用(结果文件的实际大小与从这两种方法返回的大小不同)。很明显,我遗漏了一些东西。任何帮助都将不胜感激 XML序列化: // doc is a

这是C#/.NET2.0

所以我有一个字符串,它包含XML文件的未来内容。它包含来自图像文件的元数据和二进制数据。我希望在将字符串中的数据写入文件系统后,以某种方式确定XML文件的大小

我尝试了以下方法,但两种方法都无效:

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

两者都不起作用(结果文件的实际大小与从这两种方法返回的大小不同)。很明显,我遗漏了一些东西。任何帮助都将不胜感激

XML序列化:

// doc is an XMLDocument that I've built previously
StringWriter sw = new StringWriter();
doc.Save(sw);
string XMLAsString = sw.ToString();
写入文件系统(XMLAsString作为名为data的变量传递到此函数):


谢谢

在NTFS中,如果您的文件系统设置为压缩,则最终文件可能比实际文件小。这是您的问题吗?

您缺少编码过程的工作方式。试试这个:

string data = "this is what I'm writing";
byte[] mybytes = System.Text.Encoding.UTF8.GetBytes(data);
数组的大小正好是它以某种“正常”方式写入时在磁盘上应该占用的字节数,因为UTF8是文本输出的默认编码(我认为)。可能会写入或不写入额外的EOF(文件结尾)字符,但您应该非常熟悉这一点


编辑:我认为值得大家记住的是,C#/.NET中的字符不是一个字节长,而是两个,是unicode字符,然后编码为输出格式所需的任何格式。这就是为什么任何使用
data.Length*sizeof(char)
的方法都不起作用。

在上面的示例中,什么是
data
?xml文件中如何表示二进制数据

您很可能希望对字节数组进行完全序列化,以准确猜测大小。序列化程序可能会执行任意操作,例如添加CDATA标记,如果出于某种原因需要将文件保存为UTF-16而不是UTF-8,那么这可能会使您的大小增加一倍。

您可以将其保存(或写入)到内存流中,然后确定该内存流的大小,这是在不将其写入磁盘的情况下确定实际大小的唯一方法

看不出这有什么意义,你可以只保存一个本地文件,看看最终的文件大小,然后选择如何处理它

如果您所要做的只是合理估计一个XML文件在添加了一堆编码的二进制元素后会变得多大,并且如果我们可以假设XML的其余部分与编码的二进制内容相比是可忽略的,那么这就是确定编码所引入的膨胀的问题


通常,我们会使用base64编码对二进制内容进行编码,这会导致每3个二进制字节有4个ASCII字节,即33%的膨胀。因此,估计值为data.Length*1.33333

如果要确定文件是否适合介质,必须考虑文件系统的分配大小。10字节长的文件不会占用磁盘上的10字节。空间需求以离散的步骤增加,由分配大小(也称为集群大小)决定


有关NTFS和FAT群集大小的更多信息,请参阅。

如何进行xml序列化?我要做的第一件事是除以1024,而不是除以1000。这应该对kb大小有所帮助。你是如何将数据写入文件系统的?@JFV:That(上图)在我看来像1024…我在发布问题后不久将其更改为1024。:)不过它还是关着,很有趣。是的,从方法返回的值总是大于文件系统上的实际大小。据我所知,我没有设置压缩选项。哦,仅供参考,您是对的,这返回的值比最终在FS上的值稍低。=)再次感谢。
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();
string data = "this is what I'm writing";
byte[] mybytes = System.Text.Encoding.UTF8.GetBytes(data);