如何生成唯一的文件名或路径?

4

我该如何生成一个唯一的文件名或路径?我正在寻找一个既适用于Unix(类似)操作系统又适用于Windows的解决方案。

6个回答

6
使用 boost::uuid 库:
#include <string>
using std::string;

#include <boost/lexical_cast.hpp>
using boost::lexical_cast;

#include <boost/uuid/uuid.hpp>
using boost::uuids::uuid;

#include <boost/uuid/uuid_generators.hpp>
using boost::uuids::random_generator;

#include <boost/uuid/uuid_io.hpp>

string make_uuid()
{
    return lexical_cast<string>((random_generator())());
}

使用生成的UUID作为文件名(因此路径是无关紧要的)。


2
但是这会保证一个唯一的文件名并处理竞争条件吗? - Component 10
@Component10,来自链接文档:当UUID由其中一个定义的机制生成时,它们要么保证是唯一的,不同于所有其他生成的UUID(也就是说,它以前从未被生成过,将来也永远不会再次生成),要么极有可能是唯一的(这取决于机制). 因此,对于您的问题的明确答案是它并非100%保证。然而,我已经使用了相当长的时间,并且从未发生过冲突。 - hmjd
同意,考虑到uuid的范围,我可能有点过于追求完美了。:) 我在这里看到的主要问题是如何确保在打开文件时文件不存在。关于这个问题的讨论可以在这里找到[https://dev59.com/LGHVa4cB1Zd3GeqPr_id],尽管显然你使文件名更加独特,就像你的答案一样,这种情况发生的可能性就越小。 - Component 10
1
@Component10:在实践中,你真的不需要担心GUID冲突。请参见http://thedailywtf.com/Articles/GUGUID.aspx。 - Harry Johnston

5

在两个平台上都可以使用mktemp。Windows有一个posix调用版本,位于msdn文档中,Linux调用是mktemp(3)。顺便说一下,在linux上,mktemp命令行工具只是调用了这个函数。


哦哦..是否存在任何独特的跨平台解决方案,可以生成像{XXXX_XXXX_XXXX_XXXX..}这样的名称等。 - pandreym
与 Temp 目录中的名称类似的名称在 WIN_ 上。 - pandreym
在我的 Debian 发行版中, man 3 mktemp 指示使用 mkstemp,因为 mktemp 存在安全风险。 - Colin

2

如其他地方所提到的,有tmpnam。它通常实现不良,容易导致与其他进程竞争。然而,在典型的单用户计算机上,它通常已经足够。

在我的代码中,我通常会创建一个目录,并且将进程id作为名称的一部分,并安排将所有临时文件放在其中(使用简单的计数器来变化文件名);在共享磁盘上,我也会将处理器id混淆到目录名中(但我倾向于将临时文件放在本地、非共享驱动器上,这避免了大多数问题)。


1
@user1602627,“更加独特”是什么意思?名称要么是唯一的,要么不是。你可以生成任何想要的名称,混入各种信息,如进程 ID、用户 ID、时间(如果需要,可以用微秒计算),机器 MAP 地址等等。如果需要,还可以添加从 /dev/random 中读取的一些字节。 - James Kanze
进程 ID 这个东西很好,谢谢!我会使用它。 - Alexander Ivanov

0
  • 最简单的方法:生成一个随机数,并使用其十六进制值作为文件名(除非该文件已存在,在这种情况下,您需要创建一个新文件)。

  • 更简单的方法2:如果您只需要一些不存在的文件,请使用数字(或其十六进制值)作为文件名或其中的一部分,您只需增加该数字,直到没有使用该名称的文件为止。

  • 更复杂的方法:生成GUID并将其用作文件名(再次验证它未被使用)。


0

您可以获取当前时间戳并将其用作文件名。或者只需将上一个文件名增加1即可。
例如:1.txt,2.txt等。


0
使用C库函数tmpfiletmpnam。两者在Windows和Linux下都存在。
但要注意,当使用tmpfile时,它会在关闭程序时自动删除,因此也许tmpnam更适合您。

2
从Linux手册页的tmpnam部分:永远不要使用此函数。请改用mkstemp(3)或tmpfile(3)。 - Thomas Padron-McCarthy
@ThomasPadron-McCarthy:你说得对,当有人在获取文件名和打开文件之间“劫持”你的文件时,可能会出现安全问题。通常情况下,如果是临时文件,tmpfile是正确的选择。但在这种情况下,用户可能希望使其持久化。而且我不确定mkstemp在Windows下是否可用。 - flolo
这是Linux存在的问题,而不是tmpnam本身的问题。如果实现正确,没有理由不使用tmpnam。(公平地说,它很少以安全的方式实现。但是mkstemp是Unix特有的,而不是标准C,而tmpfile不仅创建名称,还将文件作为FILE*打开,这使其变得相当无用。) - James Kanze
1
@flolo 安全问题相当牵强。虽然有可能,但不太可能;对于典型的单用户桌面机,tmpnam 可能已经足够了。(为了劫持名称,病毒必须知道它正在生成,并在生成和创建文件之间的非常非常小的时间段内运行。更不用说,在 Unix 下,至少在 Windows 下也是如此,您可以请求如果文件已经存在,则 open 失败。) - James Kanze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接