Вопрос

Я создаю файл указанного размера - мне все равно, какие данные в нем, хотя случайно будет неплохо. В настоящее время я делаю это:

        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();
            }
        }

Это не эффективно или даже правильный путь, чтобы пойти об этом. Любые более высокие решения эффективности?

Спасибо за ответы на все вопросы.

Редактировать

Управляйте некоторыми тестами на следующие методы для файла 2 ГБ (время в MS):

Метод 1: Jon Skeet

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

N / A - вне исключения памяти для файла 2 ГБ

Метод 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 - Pastant Hans (Super Fast, но данные не случайны)

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, файловую систему для 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);
        }
    }
}

При чтении файл содержит только zeros.

Вы можете использовать этот следующий класс, созданный мной для генерации случайных строк

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