10

我有一个多线程 Java 程序,可以在几秒钟内创建数百个临时文件。这些文件被放置/tmp并使用System.nanoTime().

文件名是否保证唯一?

4

4 回答 4

18

不,不能保证每次调用System.nanoTime()都会返回一个唯一值。

使用File.createTempFile()Files.createTempFile()代替。它们就是为此目的而设计的,将为您生成唯一的文件名。

于 2013-03-19T07:25:44.757 回答
3

如果您需要临时文件的唯一文件名,请使用File.createTempFile(prefix, suffix, directory)

于 2013-03-19T07:27:06.323 回答
3

至于你原来的问题

不,不是。您的线程可以在多 CPU/核心系统上同时并行运行,因此无法保证唯一值。

另外,nanoTime()仅与底层时钟一样准确。这意味着,对 nanoTime 的两次连续调用可能会返回相同的值。

引用API:“不保证值的变化频率。”

解决方案

您应该使用File.createTempFile()并让 Java 处理临时文件的唯一性。

// create temp file in /tmp with prefix  tmpfile and suffix .txt
File file = File.createTempFile("tmpfile", ".txt", new File("/tmp"));

// deletes file when the virtual machine terminate
file.deleteOnExit();

您甚至可以使用线程 id 或类似前缀的东西来保持这些 temFiles 分开。

于 2013-03-19T07:28:53.090 回答
1

如果你在一台每纳秒可以创建多个文件的机器上运行你的线程系统,你可能/将会发生名称冲突。

对此的解决方案可能是存储一个静态“索引计数器”,您可以使用它来添加/附加到文件名。

例如,您的文件名可能是System.nanoTime() + "x" + SomeClassName.index()index()方法返回索引值的位置,同时也会增加它。(您可以通过index()返回 aString或将值转换为 1 来放弃“x”)。

每次程序重新启动时“索引计数器”是否重置为 0 都没关系(我真的怀疑 JVM 实例可以在一纳秒内启动)。

只要确保使index()方法线程安全。

编辑:

我的解决方案为您提供了一种生成唯一文件名的方法。我正在使用类似的解决方案(使用“System.currentTimeMillis()”而不是System.nanoTime())为在数据库中具有临时表示的变量生成唯一 ID,它的工作原理就像一个魅力(使用前缀,它还允许批量删除数据库中的某些条目,而不仅仅是清空数据库)。

如果您对文件名本身不感兴趣,而只对拥有/使用临时文件感兴趣,我会选择 NPE 的解决方案。

于 2013-03-19T07:34:14.487 回答