我已经看到了随机命名的文件,包括使用C#:什么是生成唯一文件名的最快方法?
System.IO.Path.GetRandomFileName()
或使用
System.Guid
和附加文件扩展名的若干建议。
我的问题是:什么是生成唯一文件名的最快方法?
我已经看到了随机命名的文件,包括使用C#:什么是生成唯一文件名的最快方法?
System.IO.Path.GetRandomFileName()
或使用
System.Guid
和附加文件扩展名的若干建议。
我的问题是:什么是生成唯一文件名的最快方法?
GUID将非常快,
,因为它的实施保证Windows可以在100纳秒的时间范围内生成至少16,384个GUIDS
。 (正如其他人指出的那样,规范不能保证,只允许,但是,GUID的生成真的很快,真的)。在任何网络上的任何文件系统上发生冲突的可能性非常低。这是很安全的,尽管最好的做法是始终检查该文件名是否可用,实际上,您甚至不需要这样做。
因此,您只查看除保存本身之外的任何I/O操作,并且在测试机器上测试0.2毫秒以生成名称本身。相当快。
哇!您是否有描述此实施保证的链接源? – 2009-10-21 18:19:27
我不相信Windows gaurantees可以在100 nS中产生** 16,384个GUIDS - 只有通过GUID算法产生的值才能确保具有这种分布级别。此外,使用逻辑,每100-Ns的16k GUIDS将达到每秒1630亿GUIDS ...这意味着它只需要一个CPU周期的1/10来生成一个GUID?这没有多大意义。 – LBushkin 2009-10-21 18:23:31
看到关于GUID唯一性的这个问题http://stackoverflow.com/questions/39771/is-a-guid-unique-100-of-the-time – BlackTigerX 2009-10-21 18:24:13
如果您控制文件所在的目标位置,并且只有一个进程和线程写入该文件,只需将一些自动递增数字附加到基本名称即可。
如果您不控制目标,或者需要多线程实现,请使用GUID。
尽管我几乎总是使用GUID来解决这个问题,但LBushkin对于性能是正确的。如果你真的想要*每一滴* perf,递增一个整数并将其转换为一个字符串比生成一个Guid并将其转换为一个字符串更快......但是只有当你拥有目录的控制权时才能工作。 – 2009-10-21 19:02:21
你想System.IO.Path.GetTempFileName()
我不能说,其实无论是最快与否,但它是这样做的正确方式,这是更重要的。
+1 - 这是最简单和最好的解决方案。 – Noldorin 2009-10-21 18:32:57
这实际上创建一个文件。我认为你的意思是System.IO.Path.GetRandomFileName() – 2009-10-21 18:46:41
丹是正确的。它在Windows临时目录中创建一个文件。 – adrianbanks 2009-10-21 18:47:38
类似:
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不是免费的。
“建立一个DirectoryInfo不会免费” - 我怀疑你是正确的,特别是如果驱动器/目录不在计算机本地(网络驱动器/ NAS/etc) – 2011-03-23 18:07:58
那么我一直在写文件系统驱动程序20年,并会说雷克斯是正确的。生成一个GUID要快得多,因为它比寻找一个唯一的文件名要花费更少的开销。 GetTempFileName实际上创建了一个文件,这意味着它必须调用整个文件系统驱动程序堆栈(谁知道将会有多少个调用并切换到内核模式。)GetRandomFileName听起来更快,但我相信GUID调用甚至更快。人们没有意识到的是,即使测试文件的存在,也需要通过驱动程序堆栈进行完整调用。它实际上导致打开,获取属性并关闭(至少3次调用,具体取决于级别)。实际上,它至少需要20次函数调用并转换到内核模式。 GUIDS对独特性的保证足以满足大多数目的。
我的建议是生成名称并仅在文件不存在时才创建文件。如果是,请抛出异常并捕获它,然后生成一个新的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;
}
这不会创建名为'file_1_2_3 '? – user5226582 2018-03-02 11:39:00
虽然这会在路径中生成一个唯一的文件名(虽然它不是线程安全的),但与其他方法相比,它会非常慢,只是简单地生成一个唯一的文件名而不检查它是否已经存在。我想这个操作需要快速生成一个唯一的文件名。 Btw你的答案解决了这个问题,它可能对别人有帮助。 – Perrier 2018-03-02 11:51:02
是的,它的确如此。我的期望是增加相同的数字,但它变成了连接。需要修改代码以使其按预期工作。如果有人更正我的代码,会很感激。提前致谢。 – Bikuz 2018-03-02 11:52:08
为什么你不使用一种方法*速度够快*? – Joren 2009-10-21 18:14:28
一个很好的问题。答案是,我试图从这个文件系统密集型应用程序中挤出每盎司的性能。 – 2009-10-21 18:17:17
这真的取决于你的意思是“独一无二” - 它是否具有通用的独特性,在文件系统中是独一无二的,在同一个程序的不同线程中是唯一的......? – 2009-10-21 18:17:25