【发布时间】:2021-11-28 05:39:13
【问题描述】:
我想在将文件写入设备之前预测文件的确切大小,以便在相应驱动器中没有空间的情况下处理错误或防止崩溃。所以我有这个简单的控制台脚本,它生成文件:
using System;
using System.IO;
namespace myNamespace
{
class Program
{
static void Main(string[] args) {
byte[] myByteArray = new byte[100];
MemoryStream stream = new MemoryStream();
string fileName = "E:\\myFile.mine";
FileStream myFs = new FileStream(fileName, FileMode.CreateNew);
BinaryWriter toStreamWriter = new BinaryWriter(stream);
BinaryWriter toFileWriter = new BinaryWriter(myFs, System.Text.Encoding.ASCII);
myFs.Write(myByteArray, 0, myByteArray.Length);
for (int i = 0; i < 30000; i++) {
toStreamWriter.Write(i);
}
Console.WriteLine($"allocated memory: {stream.Capacity}" );
Console.WriteLine($"stream lenght {stream.Length}");
Console.WriteLine($"file size: {(stream.Length / 4) * 4.096 }");
toFileWriter.Write(stream.ToArray());
Console.ReadLine();
}
}
}
当我开始预测文件的大小时,我就明白了。
我将是 stream.Length / 4) * 4.096,但只要 stream.Length / 4 的 raminder 为 0。
以流加13589个整数为例
for (int i = 0; i < 13589; i++) {
toStreamWriter.Write(i);
}
我知道脚本中的文件大小为 55660,544 字节,但在资源管理器中为 57344 字节。
与添加的整数是 14000 而不是 13589 的结果相同。
当stream.Length / 4 的余数不为 0 时,我如何预测我创建的文件的确切大小?
编辑:对于运行脚本的潜在助手,您需要在每次运行脚本时删除创建的文件!当然使用您选择的路径和文件名:)
关于stream.Length / 4) * 4.096 的关系,4 表示字节大小,我猜 4.096 来自数组和文件生成,但任何进一步的解释将不胜感激。
Edit2:检查是否记录了待处理的结果:
for (int i = 13589; i <= 14000; i++) {
Console.WriteLine($"result for {i} : {(i*4 / 4) * 4.096} ");
}
您获得:
....
result for 13991 : 57307,136
result for 13992 : 57311,232
result for 13993 : 57315,328
result for 13994 : 57319,424
result for 13995 : 57323,52
result for 13996 : 57327,616
result for 13997 : 57331,712
result for 13998 : 57335,808
result for 13999 : 57339,904
result for 14000 : 57344
所以我假设文件大小适合下一个集群 + byteStream 大小,没有小数提示。这个文件大小设置逻辑对文件大小的参与是否有意义?如果流也很大?
【问题讨论】:
-
你的最终目标是不可能的。请记住,文件具有文件大小和磁盘大小。通常是不同的。请记住,您的进程可能不是唯一运行的进程。这意味着其他进程将写入磁盘并更改检查与您实际将文件写入磁盘之间的剩余磁盘空间。处理空间不足,写入函数抛出异常。
-
旁注:写入 MemoryStream 然后 一个我们通常不希望的文件(并且还施加了人为的大小限制);即使你这样做:不要使用
ToArray();有像TryGetBuffer或CopyTo这样的 API 比ToArray()更可取 -
@sbecker 感谢您的建议。运行的其他进程将用于空间可用性问题,这不是我要问的。我的最终目标是将问题放在上下文中。另一方面,当
stream.Length / 4)raminder 为0 时,可以分别使用stream.Length / 4和stream.Length / 4) * 4.096预测不同的文件大小和磁盘大小,而c# 以某种方式设置它,所以我不认为具有这两种大小并且不同与我所要求的可行性有关,即对创建的文件大小的预期 -
您是想计算出您的文件将占用多少磁盘集群,还是想计算出文件将占用多少字节?
-
@sbecker 顺便说一句,我打算将您的句柄应用到空间之外,但写入函数提案引发了异常:)