Erstellen einer Zufalls Datei in C #
-
09-10-2019 - |
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.
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.