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

Dan*_*rza 29 .net c# windows filesystems performance

我已经看到了几个关于随机命名文件的建议,包括使用

System.IO.Path.GetRandomFileName()
Run Code Online (Sandbox Code Playgroud)

或使用

System.Guid
Run Code Online (Sandbox Code Playgroud)

并附加文件扩展名.

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

Rex*_*x M 36

GUID会非常快,因为它的实现保证Windows可以在100纳秒的时间内生成至少16,384个GUID.(正如其他人指出的那样,规范不保证,只允许.但是,GUID生成确实非常非常快.真的.)任何网络上任何文件系统上发生冲突的可能性非常低.它足够安全,尽管最好始终检查文件名是否可用,但实际上你甚至不需要这样做.

因此,除了保存本身之外,您不会看到任何I/O操作,并且<0.2毫秒(在测试计算机上)生成名称本身.相当快.

  • 我不相信Windows gaurantees它可以在100 nS中生成**16,384 GUIDS - 只是GUID算法生成的值被保证具有该分发级别.此外,使用逻辑,每100-Ns 16k GUIDS每秒将达到1630亿GUID ...这意味着生成GUID所需的CPU周期不到1/10?这没有多大意义. (7认同)
  • 哇!您是否有描述此实施保证的链接源? (2认同)
  • @Dan Raymond Chen在这里分解了GUID的组成部分(它不仅仅是一个随机数):http://blogs.msdn.com/oldnewthing/archive/2008/06/27/8659071.aspx注意14位uniquifier,确保在相同的100纳秒时间内生成的GUID仍然是一对二的独特. (2认同)
  • @LBushkin你是对的,这是对规范的不好阅读.但是,我坚持认为生成GUID是如此愚蠢,你不需要费心去测量它. (2认同)

Joe*_*orn 16

你要 System.IO.Path.GetTempFileName()

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

  • 这实际上创建了一个文件.我认为你的意思是System.IO.Path.GetRandomFileName() (33认同)
  • 这有三个问题:1)无法控制文件扩展名它始终是.TMP,2)无法控制创建临时文件的目录,它总是在TEMP中,3)它使用P/Invoke让操作系统生成临时文件,所以它几乎肯定不是*最快*的方法,这是OP似乎正在寻找的. (9认同)
  • 对于使用GetTempFileName的任何人(在System.IO.Path或Win32调用中)您可能需要阅读以下文章以了解此系统的弱点:http://dotnet.org.za/markn/archive/2006/04 /15/51594.aspx此外,它可能不是最快的方式.由于需要编组,外部呼叫*很慢.创建一个新的Guid涉及对运行时的内部调用.我想这只是将调用传递给Win32 API(CoCreateGuid或UUIDCreate)... (4认同)
  • meh:对名称或路径的控制不是要求的一部分.谁说P/Invoke一定很慢? (2认同)
  • 请注意,`GetRandomFileName()`可能会创建具有您可能无法删除的扩展名的文件.例如,我遇到了扩展名为"msp"的文件的问题,一旦我不再需要临时文件,我无法删除. (2认同)

LBu*_*kin 5

如果您控制文件所在的目的地,并且只有一个进程和线程写入该文件,则只需将一些自动递增数字附加到基本名称即可。

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


小智 5

好吧,我已经写了20年的文件系统驱动程序,并会说雷克斯是正确的.生成guid要快得多,因为它比搜索唯一文件名所需的开销要少得多.GetTempFileName实际上创建了一个文件,这意味着它必须通过整个文件系统驱动程序堆栈调用(谁知道将调用多少次调用并切换到内核模式.)GetRandomFileName听起来更快,但我相信GUID调用更快.人们没有意识到的是,即使测试文件的存在,也需要通过驱动程序堆栈进行完整的调用.它实际上导致open,get属性和close(至少有3个调用,具体取决于级别).实际上,它至少需要20个函数调用并转换到内核模式.GUIDS保证其独特性足以满足大多数用途.

我的建议是生成名称并仅在文件不存在时创建文件.如果是,抛出异常并捕获它,然后生成一个新的guid并再试一次.这样,你就没有错误的机会,晚上可以轻松入睡.

另外,检查错误是如此过度.如果假设错误,代码应设计成崩溃,或者捕获异常并处理它.在异常堆栈上推送和弹出以及寻址要快得多,而不是每次检查每个函数的错误.