it-swarm.com.de

Was ist der schnellste Weg, um einen eindeutigen Dateinamen zu generieren?

Ich habe mehrere Vorschläge zum Benennen von Dateien gesehen, einschließlich der Verwendung von 

System.IO.Path.GetRandomFileName()

oder mit einem 

System.Guid

und eine Dateierweiterung anhängen. 

Meine Frage ist: Wie kann ich am schnellsten einen eindeutigen Dateinamen generieren?

29
Dan Esparza

Ein GUID wäre extrem schnell, die Implementierung gewährleistet, dass Windows in einer Zeitspanne von 100 Nanosekunden mindestens 16.384 GUIDS generieren kann. (Wie bereits erwähnt, garantiert die Spezifikation nicht, sondern lässt nur zu. Die Generierung von GUID ist jedoch wirklich, sehr schnell. Wirklich.) Die Wahrscheinlichkeit einer Kollision mit jedem Dateisystem an einem beliebigen Ort in einem Netzwerk ist sehr gering. Es ist sicher genug, dass, obwohl es die beste Praxis ist, immer zu prüfen, ob der Dateiname ohnehin verfügbar ist, in Wirklichkeit Sie das überhaupt nicht tun müssen.

Sie sehen also keine E/A-Vorgänge außer dem Sichern und <0,2 Millisekunden (auf einer Testmaschine), um den Namen selbst zu generieren. Sehr schnell.

36
Rex M

Sie wollen System.IO.Path.GetTempFileName()

Ich kann nicht wirklich sagen, ob es am schnellsten ist oder nicht, aber es ist der richtige - Weg, dies zu tun, was wichtiger ist.

16
Joel Coehoorn

Nun, ich schreibe seit 20 Jahren Dateisystemtreiber und würde sagen, dass Rex richtig ist. Das Erstellen einer Guid ist viel schneller, da sie weitaus weniger Aufwand erfordert als die Suche nach einem eindeutigen Dateinamen. GetTempFileName erstellt tatsächlich eine Datei. Das bedeutet, dass der gesamte Stack des Dateisystemtreibers aufgerufen werden muss (wer weiß, wie viele Aufrufe dies wären, und ein Wechsel in den Kernelmodus.) GetRandomFileName klingt zwar schneller, jedoch würde ich dem GUID, um noch schneller zu sein. Die Leute wissen nicht, dass sogar das Vorhandensein einer Datei zu testen, erfordert einen vollständigen Aufruf über den Treiberstack. Tatsächlich führt dies zu einem Öffnen, Abrufen von Attributen und Schließen (was mindestens 3 Aufrufe ist, abhängig von der Ebene.) In Wirklichkeit sind es mindestens 20 Funktionsaufrufe und ein Übergang zum Kernelmodus. GUIDS Garantie der Einzigartigkeit ist für die meisten Zwecke gut genug.

Meine Empfehlung ist, den Namen zu generieren und die Datei nur dann zu erstellen, wenn sie nicht existiert. Wenn dies der Fall ist, werfen Sie eine Ausnahme aus und fangen Sie sie, generieren Sie eine neue GUID und versuchen Sie es erneut. Auf diese Weise haben Sie keine Chance auf Fehler und können nachts problemlos schlafen.

Nebenbei bemerkt ist die Überprüfung auf Fehler so übertrieben. Code sollte so gestaltet sein, dass er abstürzt, wenn Annahmen falsch sind, oder Ausnahmen fangen und sich damit befassen. Es ist viel schneller zu Push und Pop und Adressierung auf dem Ausnahmestapel, als jedes Mal bei jeder Funktion nach einem Fehler zu suchen.

5
Jordan

Wenn Sie das Ziel steuern, an dem sich die Dateien befinden, und es nur einen Prozess und einen Thread gibt, der dorthin schreibt, fügen Sie einfach eine automatisch ansteigende Nummer an einen Basisnamen an.

Wenn Sie das Ziel nicht steuern oder eine Multithread-Implementierung benötigen, verwenden Sie eine GUID.

3
LBushkin

Wenn Sie das Verzeichnis steuern, können Sie Ihre Datei basierend auf lastWriteTime benennen:

DirectoryInfo info = new DirectoryInfo(directoryPath);
long uniqueKey = info.LastWriteTime.Ticks+1L;
string filename = String.Format("file{0}.txt", key);

Sie müssen jedoch die Leistung dieses Codes überprüfen: Ich denke, das Erstellen einer DirectoryInfo ist nicht kostenlos.

1
Stéphane

Sie können so etwas tun: 

file.MoveTo(deletedfilesdir + @"\" + f.Name + **DateTime.Now.ToFileTimeUtc()** + f.Extension);
0
Haroon

Verwenden Sie ein Int und erhöhen Sie es für jede Datei.

0
Tom B

Ich hoffe, diese selbst iterative Funktion wird jemandem helfen, einen eindeutigen Dateinamen zu erzeugen. 

public string getUniqueFileName(int i, string fullpath, string filename)
{
    string lstDir = fullpath.Substring(0, fullpath.LastIndexOf('\\'));
    string name = Path.GetFileName(fullpath);
    string path = fullpath;

    if (name != filename)
        path = Path.Combine(lstDir, filename);

    if (System.IO.File.Exists(path))
    {
        string ext = Path.GetExtension(name);
        name = Path.GetFileNameWithoutExtension(name);                
        i++;
        filename = getUniqueFileName(i, fullpath, name + "_" + i + ext);
    }

    return filename;
}
0
Bikuz