C#:生成唯一文件名的最快方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1602578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: What is the fastest way to generate a unique filename?
提问by Dan Esparza
I've seen several suggestions on naming files randomly, including using
我已经看到了一些关于随机命名文件的建议,包括使用
System.IO.Path.GetRandomFileName()
or using a
或使用
System.Guid
and appending a file extension.
并附加文件扩展名。
My question is: What is the fastest way to generate a unique filename?
我的问题是:生成唯一文件名的最快方法是 什么?
采纳答案by Rex M
A GUID would be extremely fast, since it's implementation guarantees Windows can generate at least 16,384 GUIDS in a 100-nanosecond timespan. (As others pointed out, the spec doesn't guarantee, only allows for. However, GUID generation is really, really fast. Really.) The likelihood of collision on any filesystem anywhere on any network is very low. It's safe enough that although it'd be best practice to always check to see if that filename is available anyway, in reality you would never even need to do that.
GUID 会非常快,因为它的实现保证 Windows 可以在 100 纳秒的时间跨度内生成至少 16,384 个 GUID。(正如其他人指出的那样,规范不保证,只允许。然而,GUID 生成真的非常快。真的。)任何网络上任何地方的任何文件系统发生冲突的可能性都非常低。尽管最好始终检查该文件名是否可用,但它足够安全,但实际上您甚至不需要这样做。
So you're looking at no I/O operations except the save itself, and <0.2 milliseconds (on a test machine) to generate the name itself. Pretty fast.
因此,除了保存本身之外,您没有看到任何 I/O 操作,并且 <0.2 毫秒(在测试机器上)来生成名称本身。相当快。
回答by LBushkin
If you control the destination where the files will be located, and there is only one process and thread that writes to it, just append some auto-incrementing number to a base name.
如果您控制文件所在的目的地,并且只有一个进程和线程写入文件,只需在基本名称后附加一些自动递增的数字即可。
If you don't control the destination, or need a multithreaded implementation, use a GUID.
如果您不控制目标,或者需要多线程实现,请使用 GUID。
回答by Joel Coehoorn
You want System.IO.Path.GetTempFileName()
你要 System.IO.Path.GetTempFileName()
I can't actually say whether it's fastestor not, but it's the rightway to do this, which is more important.
我实际上不能说它是否最快,但这是做到这一点的正确方法,这更重要。
回答by Tom B
Use an Int and increment it for each file.
使用 Int 并为每个文件增加它。
回答by Haroon
You can do something like:
您可以执行以下操作:
file.MoveTo(deletedfilesdir + @"\" + f.Name + **DateTime.Now.ToFileTimeUtc()** + f.Extension);
回答by Stéphane
If you control the directory, you could name your file based on the lastWriteTime:
如果您控制目录,您可以根据 lastWriteTime 命名您的文件:
DirectoryInfo info = new DirectoryInfo(directoryPath);
long uniqueKey = info.LastWriteTime.Ticks+1L;
string filename = String.Format("file{0}.txt", key);
But you have to check performances of this code: I guess building a DirectoryInfo does not come for free.
但是您必须检查此代码的性能:我猜构建 DirectoryInfo 不是免费的。
回答by Jordan
Well I have been writing file system drivers for 20 years and would say Rex is correct. Generating a guid is much much faster, since it requires far less overhead than searching for a unique file name. GetTempFileName actually creates a file, which means it has to call through the entire file system driver stack (who knows how many calls that would be and a switch into kernel mode.) GetRandomFileName sounds like it is faster, however I would trust the GUID call to be even faster. What people don't realize is that even testing for the existence of a file requires a complete call through the driver stack. It actually results in an open, get attributes and close (which is at least 3 calls, depending on the level.) In reality it is a minimum of 20 function calls and a transition to kernel mode. GUIDS guarentee of uniqueness is good enough for most purposes.
好吧,我已经写了 20 年的文件系统驱动程序,并且会说 Rex 是正确的。生成 guid 要快得多,因为与搜索唯一文件名相比,它需要的开销要少得多。GetTempFileName 实际上创建了一个文件,这意味着它必须调用整个文件系统驱动程序堆栈(谁知道会有多少调用并切换到内核模式。)GetRandomFileName 听起来更快,但我相信 GUID 调用甚至更快。人们没有意识到,即使测试文件是否存在也需要通过驱动程序堆栈进行完整调用。它实际上导致打开、获取属性和关闭(至少 3 次调用,具体取决于级别)。实际上,它至少需要 20 次函数调用并转换到内核模式。
My recommendation is to generate the name and create the file only if it doesn't exist. If it does, throw an exception and catch it, then generate a new guid and try again. That way, you have zero chance of errors and can sleep easy at night.
我的建议是生成名称并仅在文件不存在时创建该文件。如果是,则抛出异常并捕获它,然后生成一个新的 guid 并重试。这样,您出错的机会为零,晚上可以轻松入睡。
On a side note, checking for errors is so overdone. Code should be designed to crash if assumptions are wrong, or catch exceptions and deal with it then. Its much faster to push and pop and address on the exception stack, than to check everytime on every function for an error.
顺便说一句,检查错误太过分了。如果假设错误,代码应该被设计为崩溃,或者捕获异常然后处理它。在异常堆栈上推送、弹出和寻址比每次检查每个函数是否有错误要快得多。
回答by Bikuz
I hope this self iterative function will help someone to generate a unique filename.
我希望这个自迭代函数能帮助某人生成一个唯一的文件名。
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;
}