Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:生成唯一文件名的最快方法是什么?_C#_.net_Windows_Performance_Filesystems - Fatal编程技术网

C#:生成唯一文件名的最快方法是什么?

C#:生成唯一文件名的最快方法是什么?,c#,.net,windows,performance,filesystems,C#,.net,Windows,Performance,Filesystems,我看到了一些关于随机命名文件的建议,包括使用 System.IO.Path.GetRandomFileName() 或者使用 System.Guid 并附加一个文件扩展名 我的问题是:生成唯一文件名的最快方法是什么?GUID会非常快,因为它的实现保证Windows在100纳秒的时间跨度内至少可以生成16384个GUID。(正如其他人指出的,该规范不保证,只允许。但是,GUID生成非常非常快。非常。)在任何网络上任何位置的任何文件系统上发生冲突的可能性都非常低。尽管总是检查文件名是否可用是最好

我看到了一些关于随机命名文件的建议,包括使用

System.IO.Path.GetRandomFileName()
或者使用

System.Guid
并附加一个文件扩展名


我的问题是:生成唯一文件名的最快方法是什么?

GUID会非常快,因为它的实现保证Windows在100纳秒的时间跨度内至少可以生成16384个GUID。(正如其他人指出的,该规范不保证,只允许。但是,GUID生成非常非常快。非常。)在任何网络上任何位置的任何文件系统上发生冲突的可能性都非常低。尽管总是检查文件名是否可用是最好的做法,但实际上你根本不需要这样做


因此,除了保存本身,您没有看到任何I/O操作,并且如果您控制文件将位于的目标位置,并且只有一个进程和线程向其写入,那么只需在基本名称中附加一些自动递增的数字


如果您不控制目标,或者需要多线程实现,请使用GUID。

您需要的
System.IO.Path.GetTempFileName()


实际上我不能说它是否最快,但这是正确的方法,更重要的是。

使用Int并对每个文件递增。

您可以执行以下操作:

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

如果控制目录,则可以根据lastWriteTime为文件命名:

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

但是您必须检查这段代码的性能:我想构建DirectoryInfo并不是免费的。

我已经编写文件系统驱动程序20年了,我会说Rex是正确的。生成guid的速度要快得多,因为它所需的开销远小于搜索唯一的文件名。GetTempFileName实际上创建了一个文件,这意味着它必须通过整个文件系统驱动程序堆栈进行调用(谁知道会有多少次调用并切换到内核模式。)GetRandomFileName听起来更快,但我相信GUID调用会更快。人们没有意识到的是,即使测试文件是否存在,也需要通过驱动程序堆栈进行完整的调用。它实际上会导致一个open、get attributes和close(根据级别的不同,至少有3个调用)。实际上,它至少需要20个函数调用,并转换到内核模式。对于大多数目的来说,guid的唯一性保证已经足够好了

我的建议是只在文件不存在时生成名称并创建文件。如果出现异常,则抛出异常并捕获它,然后生成新的guid并重试。这样,你就不会犯错误,晚上也可以睡得很安稳


另一方面,检查错误太过分了。如果假设错误,代码应该设计为崩溃,或者捕获异常并处理它。在异常堆栈上推送、弹出和寻址比每次检查每个函数是否有错误要快得多。

我希望这个自迭代函数将有助于生成唯一的文件名

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

你为什么不用一种足够快的方式呢?一个很好的问题。答案是,我正试图从这个文件系统密集型应用程序中挤出每一盎司的性能。这真的取决于你所说的“唯一性”——它是普遍唯一的,在一个文件系统中是唯一的,在同一个程序中的不同线程之间是唯一的…?@Anders:这一点很好。我已经有了一个文件夹路径——所以我的意思是“在给定的文件夹中是唯一的”,你几乎肯定不在乎。假设您要对该随机文件名执行任何IO操作,这将使创建该文件名所需的时间相形见绌。把优化的重点放在能带来不同的地方。哇!您是否有描述此实现保证的链接源?我不相信Windows Gaurantes能够在100 nS内生成16384个GUID-只是GUID算法生成的值需要具有该级别的分布。此外,使用逻辑,每100ns 16k个guid将是每秒1630亿个guid。。。这意味着产生GUID所需的CPU周期不到1/10?这没什么意义。看看这个关于GUID唯一性的问题@Dan Raymond Chen在这里分解了GUID的组成部分(它不仅仅是一个随机数):注意14位的uniquifier,它确保在相同的100纳秒时间跨度内生成的GUID仍然是2^14唯一的。@LBushkin你说得对,这是一个糟糕的规范阅读。然而,我坚持的断言,生成GUID是如此愚蠢的快,你不需要费心衡量它。这实际上创建了一个文件。我想你的意思是System.IO.Path.GetRandomFileName()这有三个问题:1)无法控制文件扩展名始终是.TMP,2)无法控制创建临时文件的目录,它始终在temp中,3)它使用P/Invoke让操作系统生成临时文件,因此这几乎肯定不是最快的方法,这正是OP想要的。meh:对名称或路径的控制不是要求的一部分。谁说P/Invoke一定很慢?对于任何使用GetTempFileName(在System.IO.Path或Win32调用中)的人来说,您可能希望阅读以下文章来了解此系统的弱点:而且,这可能不是最快的方法。由于需要编组,外部调用速度较慢。创建新Guid涉及对运行时的内部调用。我想,只是将调用传递到Win32 API以获得相同的(CoCreateGuid或UUIDCreate)…请小心
GetRandomFileName()
可能会创建扩展名无法删除的文件。例如,我遇到了扩展名为“msp”的文件的问题,一旦不再需要临时文件,我就无法删除这些文件。虽然我几乎总是使用GUID来解决这个问题,但LBushkin在性能方面是正确的。如果你真的想