我正在创建一个下载应用程序,希望在文件下载之前在硬盘驱动器上进行预算房间,因为它们可能很大,而且没有人喜欢看到“此驱动器已满,请删除一些文件,然后重试。 “因此,从那一头,我写了这篇文章。

// Quick, and very dirty
System.IO.File.WriteAllBytes(filename, new byte[f.Length]);

它是有效的,至少直到你下载了一个几百MB甚至GB的文件,并且如果没有完全清除页面文件并完全杀死你的系统内存,你就会让Windows陷入疯狂的混乱之中。哎呀。

因此,有了更多的启发,我开始使用以下算法。

using (FileStream outFile = System.IO.File.Create(filename))
{
    // 4194304 = 4MB; loops from 1 block in so that we leave the loop one 
    // block short
    byte[] buff = new byte[4194304];
    for (int i = buff.Length; i < f.Length; i += buff.Length)
    {
        outFile.Write(buff, 0, buff.Length);
    }
    outFile.Write(buff, 0, f.Length % buff.Length);
}

这甚至可以很好地工作,并且不会遇到上一个解决方案的严重内存问题。但它仍然很慢,尤其是在较旧的硬件上,因为它将数据(可能是 GB 的数据)写入磁盘。

问题是这样的:有没有更好的方法来完成同样的事情?有没有办法告诉 Windows 创建一个 x 大小的文件并简单地在文件系统上分配空间,而不是实际写出一吨数据。我根本不关心初始化文件中的数据(我使用的协议 - bittorrent - 为其发送的文件提供哈希值,因此随机未初始化数据的最坏情况是我得到了一个幸运的巧合和文件的一部分是正确的)。

有帮助吗?

解决方案

文件流.SetLength 就是你想要的那个。语法:

public override void SetLength(
    long value
)

其他提示

如果您必须创建该文件,我认为您可以这样做:

using (FileStream outFile = System.IO.File.Create(filename))
{
    outFile.Seek(<length_to_write>-1, SeekOrigin.Begin);
    OutFile.WriteByte(0);
}

其中 length_to_write 是要写入的文件的大小(以字节为单位)。我不确定我的 C# 语法是否正确(不是在计算机上进行测试),但我过去在 C++ 中做过类似的事情并且它有效。

不幸的是,仅靠追求终点并不能真正做到这一点。这会将文件长度设置为很大,但实际上可能不会分配磁盘块进行存储。所以当你去写文件的时候,还是会失败。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top