我正在创建一个指定大小的文件 - 我不在乎其中的数据,尽管随机是好的。目前,我正在这样做:

        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-汉斯传球者(超快,但数据不是随机的)

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

257、287、3、3、2、3等

有帮助吗?

解决方案

好吧,a 非常 简单解决方案:

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 多次 - 警告它不是线程安全。

其他提示

没有更快的方法,然后利用NTF中内置的稀疏文件支持,即硬盘上使用的窗口的文件系统。此代码在一秒钟的一秒钟内创建一个千兆文件:

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的随机字节。

一个改进将是用数据填充所需尺寸的缓冲区,然后一次冲洗。

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