Frage

Ich bin eine Datei von einer bestimmten Größe zu schaffen - ist mir egal, welche Daten in es ist, obwohl zufällig wäre schön. Derzeit wird diese ich tue:

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

Dies ist nicht effizient oder sogar der richtige Weg, um darüber zu gehen. Jede höhere Performance-Lösungen?

Danke für alle Antworten.

Bearbeiten

Ran einige Tests auf den folgenden Methoden für eine 2-GB-Datei (Zeit in ms):

Methode 1: Jon Skeet

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

N / A - Nicht genügend Speicher Ausnahme für 2 GB Datei

Methode 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

Methode 3 - Hans Passant (Super Fast aber Daten nicht zufällig ist)

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

257, 287, 3, 3, 2, 3 usw.

War es hilfreich?

Lösung

Nun, eine sehr einfache Lösung:

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

Ein etwas mehr Speicher effiziente Version:)

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

Wenn Sie jedoch tun dies mehrmals in sehr kurz hintereinander eine neue Instanz von Random jedes Mal erstellen, können Sie doppelte Daten. Sehen Sie mein Artikel auf Zufälligkeit für weitere Informationen - Sie könnten vermeiden diese mit System.Security.Cryptography.RandomNumberGenerator ... oder durch die gleiche Instanz von Random Wiederverwendung mehrmals -. mit dem Vorbehalt, dass es nicht Thread-sicher ist

Andere Tipps

Es gibt keinen schnelleren Weg, dann nutzen Sie die Datei mit geringer Dichte Unterstützung in NTFS gebaut nehmen, das Dateisystem für Windows verwendet, auf Festplatten. Dieser Code erstellen ein Gigabyte-Datei in einem Bruchteil einer Sekunde:

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

Beim Lesen der Datei enthält nur Nullen.

Sie können diese folgende Klasse verwenden, erstellt von mir für zufällige Zeichenfolgen generieren

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

    }

}

für die Verwendung

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

Die effiziente Möglichkeit, eine große Datei zu erstellen:

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

Allerdings wird diese Datei (mit Ausnahme des „Test“ am Ende) leer sein. Nicht klar, was genau Sie versuchen zu tun - große Datei mit Daten, oder einfach nur große Datei. Sie können dies ändern, um dünn zu einigen Daten in der Datei zu schreiben, aber ohne ihn vollständig zu füllen. Wenn Sie die gesamte Datei mit zufälligen Daten gefüllt wollen, dann ist die einzige Art und Weise kann ich mich vorstellen wird mit Zufall von Jon Bytes oben.

Eine Verbesserung wäre es, einen Puffer der gewünschten Größe mit den Daten zu füllen und alles auf einmal gespült wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top