我不一定要使用UUID,因为它们相当长。
该文件仅需要在其目录中唯一。
我想到的一个想法是使用File.createTempFile(String prefix, String suffix)
,但这似乎是错误的,因为该文件不是临时文件。
需要处理在同一毫秒内创建的两个文件的情况。
Answers:
好吧,您可以使用3参数版本: File.createTempFile(String prefix, String suffix, File directory)
它将让您将其放置在所需的位置。除非您告知,否则Java将不会像对待其他任何文件一样对待它。唯一的缺点是文件名必须保证至少8个字符长(前缀至少3个字符,再加上该函数生成的5个或更多字符)。
如果那对您来说太长了,我想您总是可以从文件名“ a”开始,然后遍历“ b”,“ c”等,直到找到一个不存在的文件名。
我会使用Apache Commons Lang库(http://commons.apache.org/lang)。
有一个类org.apache.commons.lang.RandomStringUtils
可用于生成给定长度的随机字符串。非常方便,不仅用于生成文件名!
这是示例:
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)));
除非同一秒内创建的文件数太大。
如果是这样的话,名字也没关系
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
查看File javadoc,方法createNewFile将仅在文件不存在时创建文件,并且将返回一个布尔值以说明文件是否已创建。
您也可以使用exist()方法:
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);
如果您有权访问数据库,则可以在文件名中创建和使用序列。
select mySequence.nextval from dual;
它会被保证是唯一的,并且不会太大(除非您要抽出大量文件)。
//Generating Unique File Name
public String getFileName() {
String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
return "PNG_" + timeStamp + "_.png";
}
File.createTempFile
不引擎盖下
看起来您已经找到了一些创建唯一文件名的解决方案,所以我将不理它。我将以这种方式测试文件名:
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;
为什么不使用同步来处理多线程。这是我的解决方案,它可以生成一个短文件名,并且是唯一的。
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'};
吹是测试的主要功能,它的工作。
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());
}