我有一个多线程Java程序,可以在几秒钟内创建数百个临时文件。这些文件放在/tmp
中,并使用System.nanoTime()
命名。
文件名是否保证唯一?
答案 0 :(得分:18)
不,无法保证每次拨打System.nanoTime()
都会返回唯一值。
改为使用File.createTempFile()
或Files.createTempFile()
。它们专为此目的而设计,并将为您生成唯一的文件名。
答案 1 :(得分:3)
如果您需要临时文件的唯一文件名,请使用File.createTempFile(prefix, suffix, directory)。
答案 2 :(得分: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 appart。
答案 3 :(得分:1)
如果在每纳秒可以创建多个文件的计算机上运行线程系统,则可能/将发生名称冲突。
对此的解决方案可能是存储一个静态“索引计数器”,您可以使用它来预先添加/附加到文件名。
例如,您的文件名可能是System.nanoTime() + "x" + SomeClassName.index()
,其中index()
方法将返回索引的值,同时也会递增它。 (您可以通过index()
返回String
或将值转换为1来抛弃“x”。
每次程序重新启动时,“索引计数器”是否重置为0都没关系(我真的怀疑JVM实例可以在一纳秒内启动)。
确保index()
方法是线程安全的。
编辑:
我的解决方案为您提供了一种生成唯一文件名的方法。我使用类似的解决方案(使用“System.currentTimeMillis()”而不是System.nanoTime()
)来为在数据库中具有临时表示的变量生成唯一ID,并且它像魅力一样工作(使用前缀,它也是允许批量删除DB中的某些条目,而不仅仅是清空DB)。
如果您对文件名本身不感兴趣,但只对使用/使用临时文件感兴趣,我会选择NPE的解决方案。