在Java中生成一个唯一的短文件名的最好方法是什么?

我不一定要使用UUID,因为它们相当长。

该文件只需要在其目录中是唯一的。

想到的一个想法是使用File.createTempFile(String prefix, String suffix) ,但这似乎是错误的,因为该文件不是临时的。

需要处理在同一个毫秒内创build的两个文件的情况。

那么,你可以使用3参数版本: File.createTempFile(String prefix, String suffix, File directory) ,这将让你把它放在你想要的地方。 除非你告诉它,否则Java不会以任何其他文件的方式对待它。 唯一的缺点是文件名至less保证8个字符(后缀最less3个字符,加上5个或更多字符)。

如果这对你来说太长了,我想你总是可以从文件名“a”开始,然后循环“b”,“c”等,直到find一个不存在的文件。

我会使用Apache Commons Lang库( http://commons.apache.org/lang )。

有一个类org.apache.commons.lang.RandomStringUtils可以用来生成给定长度的随机string。 非常方便,不仅适用于文件名生成!

这是一个例子:

 String ext = "dat"; File dir = new File("/home/pregzt"); String name = String.format("%s.%s", RandomStringUtils.randomAlphanumeric(8), ext); File file = new File(dir, name); 

我使用时间戳

 new File( simpleDateFormat.format( new Date() ) ); 

并将simpleDateFormat初始化为如下所示:

 new SimpleDateFormat("File-ddMMyy-hhmmss.SSS.txt"); 

编辑

关于什么

 new File(String.format("%s.%s", sdf.format( new Date() ), random.nextInt(9))); 

除非在同一秒内创build的文件数量太高。

如果是这样的话,名字不重要

  new File( "file."+count++ ); 

:P

这适用于我:

 String generateUniqueFileName() { String filename = ""; long millis = System.currentTimeMillis(); String datetime = new Date().toGMTString(); datetime = datetime.replace(" ", ""); datetime = datetime.replace(":", ""); String rndchars = RandomStringUtils.randomAlphanumeric(16); filename = rndchars + "_" + datetime + "_" + millis; return filename; } 

// USE:

 String newFile; do{ newFile=generateUniqueFileName() + "." + FileExt; } while(new File(basePath+newFile).exists()); 

输出文件名应该如下所示:

 2OoBwH8OwYGKW2QE_4Sep2013061732GMT_1378275452253.Ext 

看一下文件javadoc ,createNewFile方法只会在文件不存在的情况下创build文件,并返回一个布尔值来表示文件是否被创build。

你也可以使用exists()方法:

 int i = 0; String filename = Integer.toString(i); File f = new File(filename); while (f.exists()) { i++; filename = Integer.toString(i); f = new File(filename); } f.createNewFile(); System.out.println("File in use: " + f); 

如果您有权访问数据库,则可以在文件名中创build和使用序列。

 select mySequence.nextval from dual; 

它将被保证是唯一的,不应该太大(除非你抽出大量的文件)。

为什么不只是使用基于时间戳的东西..?

结合其他答案,为什么不使用带有随机值的ms时间戳; 重复,直到没有冲突,这实际上将永远不会。

例如:File-ccyymmdd -hhmmss-mmm-rrrrrr.txt

如何生成基于时间戳四舍五入到最接近的毫秒,或者你需要什么精度…然后使用锁来同步访问function。

如果存储最后生成的文件名,则可以根据需要附加连续字母或更多数字以使其唯一。

或者,如果你宁愿不加锁,使用一个时间步加一个线程ID,并确保该函数花费的时间超过一毫秒,或等待,以便它。

看起来你已经有了一些解决scheme来创build一个独特的文件名,所以我会一个人留下。 我会这样testing文件名:

  String filePath; boolean fileNotFound = true; while (fileNotFound) { String testPath = generateFilename(); try { RandomAccessFile f = new RandomAccessFile( new File(testPath), "r"); } catch (Exception e) { // exception thrown by RandomAccessFile if // testPath doesn't exist (ie: it can't be read) filePath = testPath; fileNotFound = false; } } //now create your file with filePath 

这也适用

 String logFileName = new SimpleDateFormat("yyyyMMddHHmm'.txt'").format(new Date()); logFileName = "loggerFile_" + logFileName; 

我明白现在回答这个问题为时已晚。 但我想我应该把这个看起来和其他解决scheme有所不同。

我们可以连接线程名和当前时间戳作为文件名。 但是有了这样一个问题,像一些线程名称包含像“\”这样的特殊字符,可以在创build文件名时产生问题。 因此,我们可以从线程名称中删除特殊字符,然后连接线程名称和时间戳

 fileName = threadName(after removing special charater) + currentTimeStamp 

为什么不使用synchronized来处理multithreading。 这里是我的解决scheme,它可以生成一个简短的文件名,并且是唯一的。

 private static synchronized String generateFileName(){ String name = make(index); index ++; return name; } private static String make(int index) { if(index == 0) return ""; return String.valueOf(chars[index % chars.length]) + make(index / chars.length); } private static int index = 1; private static char[] chars = {'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n', 'o','p','q','r','s','t', 'u','v','w','x','y','z'}; 

吹是testing的主要function,是工作。

 public static void main(String[] args) { List<String> names = new ArrayList<>(); List<Thread> threads = new ArrayList<>(); for (int i = 0; i < 100; i++) { Thread thread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 1000; i++) { String name = generateFileName(); names.add(name); } } }); thread.run(); threads.add(thread); } for (int i = 0; i < 10; i++) { try { threads.get(i).join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(names); System.out.println(names.size()); }