在C#中创建随机文件

我正在创建一个指定大小的文件 – 我不关心它中的数据,虽然随机会很好。 目前我这样做:

var sizeInMB = 3; // Up to many Gb using (FileStream stream = new FileStream(fileName, FileMode.Create)) { using (BinaryWriter writer = new BinaryWriter(stream)) { while (writer.BaseStream.Length <= sizeInMB * 1000000) { writer.Write("a"); //This could be random. Also, larger strings improve performance obviously } writer.Close(); } } 

这不是有效的,甚至是正确的方法。 更高性能的解决方案?

感谢所有的答案。

编辑

对2Gb文件的以下方法进行一些测试(以ms为单位的时间):

方法1:Jon Skeet

 byte[] data = new byte[sizeInMb * 1024 * 1024]; Random rng = new Random(); rng.NextBytes(data); File.WriteAllBytes(fileName, data); 

N / A – 2Gb文件的内存不足

方法2:Jon Skeet

 byte[] data = new byte[8192]; Random rng = new Random(); using (FileStream stream = File.OpenWrite(fileName)) { for (int i = 0; i < sizeInMB * 128; i++) { rng.NextBytes(data); stream.Write(data, 0, data.Length); } } 

@ 1K – 45,868,23,283,23,346

@ 128K – 24,877,20,585,20,716

@ 8Kb – 30,426,22,936,22,936

方法3 – Hans Passant(超快但数据不是随机的)

 using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) { fs.SetLength(sizeInMB * 1024 * 1024); } 

257,287,3,3,2,3等

嗯,一个非常简单的解决方案

 byte[] data = new byte[sizeInMb * 1024 * 1024]; Random rng = new Random(); rng.NextBytes(data); File.WriteAllBytes(fileName, data); 

内存效率稍高的版本:)

 // Note: block size must be a factor of 1MB to avoid rounding errors :) const int blockSize = 1024 * 8; const int blocksPerMb = (1024 * 1024) / blockSize; byte[] data = new byte[blockSize]; Random rng = new Random(); using (FileStream stream = File.OpenWrite(fileName)) { // There for (int i = 0; i < sizeInMb * blocksPerMb; i++) { rng.NextBytes(data); stream.Write(data, 0, data.Length); } } 

但是,如果您在非常快速的连续中多次执行此操作,则每次都会创建一个新的Random实例,您可能会获得重复数据。 有关更多信息,请参阅我的随机性文章 - 您可以使用System.Security.Cryptography.RandomNumberGenerator来避免这种情况......或者通过多次重复使用相同的Random实例 - 但需要注意的是它不是线程安全的。

没有更快的方法可以利用NTFS内置的稀疏文件支持,NTFS是用于硬盘的Windows文件系统。 此代码在几分之一秒内创建一个千兆字节的文件:

 using System; using System.IO; class Program { static void Main(string[] args) { using (var fs = new FileStream(@"c:\temp\onegigabyte.bin", FileMode.Create, FileAccess.Write, FileShare.None)) { fs.SetLength(1024 * 1024 * 1024); } } } 

读取时,该文件仅包含零。

您可以使用我创建的以下类来生成随机字符串

 using System; using System.Text; public class RandomStringGenerator { readonly Random random; public RandomStringGenerator() { random = new Random(); } public string Generate(int length) { if (length < 0) { throw new ArgumentOutOfRangeException("length"); } var stringBuilder = new StringBuilder(); for (int i = 0; i < length; i++) { char ch = (char)random.Next(0,255 ); stringBuilder.Append(ch); } return stringBuilder.ToString(); } } 

使用

  int length = 10; string randomString = randomStringGenerator.Generate(length); 

创建大文件的有效方法:

  FileStream fs = new FileStream(@"C:\temp\out.dat", FileMode.Create); fs.Seek(1024 * 6, SeekOrigin.Begin); System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); fs.Write(encoding.GetBytes("test"), 0, 4); fs.Close(); 

但是这个文件是空的(除了最后的“测试”)。 不清楚你正在尝试做什么 – 带有数据的大文件,或者只是大文件。 您可以修改它以稀疏地在文件中写入一些数据,但不完全填写它。 如果你确实希望整个文件充满随机数据,那么我能想到的唯一方法是使用Jon上面的随机字节。

改进之处在于用数据填充所需大小的缓冲区并立即将其全部刷新。