Создание случайного файла в C#
Я создаю файл определенного размера - мне все равно, какие данные в нем, хотя random было бы неплохо. В настоящее время я делаю это:
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: Джон Скит
byte[] data = new byte[sizeInMb * 1024 * 1024];
Random rng = new Random();
rng.NextBytes(data);
File.WriteAllBytes(fileName, data);
N / A - Out исключение памяти для файла 2Gb
Метод 2: Джон Скит
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 etc.
5 ответов
Ну очень простое решение:
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, файловую систему для 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();
однако этот файл будет пустым (за исключением "теста" в конце). Не понятно, что именно вы пытаетесь сделать-большой файл с данными, или просто большой файл. Вы можете изменить это, чтобы редко записывать некоторые данные в файл, но не заполняя его полностью. Если вы хотите, чтобы весь файл был заполнен случайными данными, единственный способ, который я могу придумать, - это использовать случайные байты от Джона выше.