Как эффективнее создать большой файл с ненужными данными указанного размера? - PullRequest
0 голосов
/ 31 января 2012

Я хочу написать программу, которая может генерировать большие файлы (1 ГБ и более), заполненные не более чем случайным мусором.

Проблема заключается в том, что если я пытаюсь создать файл размером более100 МБ мое приложение использует более 500 МБ ОЗУ и занимает вечно.

Шаги, которые я использую:

  • использование цикла для создания ненужных данных и добавления их в массив символов.
  • сохранить все символы из массива в переменной.
  • сохранить данные из переменной в файл.

Есть ли лучшее решение для этого?Может быть, какой-нибудь ярлык?

Вот с чем я работаю:

namespace Fake_File_Creator
{
    public partial class MainWindow : Form
    {
        private string text;
        private List<char> stringChars;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnNewFile_Click(object sender, EventArgs e)
        {
            sfdNewFile.Filter = "All Files|*.*";

            if (sfdNewFile.ShowDialog() == DialogResult.OK)
            {
                lblMessage.Text = "Generating data...";
                bwCreateData.RunWorkerAsync((int)nudSize.Value * 1024000);
            }
        }

        private void bwCreateData_DoWork(object sender, DoWorkEventArgs e)
        {
            var random = new Random();
            var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 ~!@#$%^&*()_+ /.,'[];{}|:<>?";

            stringChars = new List<char>();

            for (int i = 0; i < (int)e.Argument; i++)
            {
                stringChars.Add(chars[random.Next(chars.Length)]);
            }

            text = new string(stringChars.ToArray());
        }

        void bwCreateData_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lblMessage.Text = "Saving file...";
            bwCreateFile.RunWorkerAsync();
        }

        private void bwCreateFile_DoWork(object sender, DoWorkEventArgs e)
        {
            using (StreamWriter outfile = new StreamWriter(sfdNewFile.FileName))
            {
                outfile.Write(text);
            }
        }

        void bwCreateFile_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lblMessage.Text = "File succesfully created...";

            text = string.Empty;
            stringChars.Clear();
            stringChars = null;
            GC.Collect(); 
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 31 января 2012

Просто запишите тонну данных в файл напрямую, а не сохраняйте в памяти в строке «text».

Вы можете вызывать outfile.Write («нежелательный текст») в цикле.

1 голос
/ 31 января 2012

Может быть полезно предварительно выделить список с помощью

stringChars = new List<char>((int)e.Argument);

Важен ли набор символов?Вместо этого вы можете попробовать сгенерировать случайное число от 1 до 94 (или около того), добавить 31 и преобразовать в ASCII-символ.Таким образом вы получите большинство печатных наборов ascii и сохраните результаты поиска в массиве chars.

EDIT ... Я согласен с предыдущим постером (Джеймс Коттер) - зачем писатьк вашему временному массиву, когда вы можете просто сделать

streamWriter.Write(randomCharacter)
...