我不一定要使用 UUID,因为它们相当长。
该文件只需要在其目录中是唯一的。
想到的一种想法是使用File.createTempFile(String prefix, String suffix)
,但这似乎是错误的,因为该文件不是临时文件。
需要处理在同一毫秒内创建两个文件的情况。
我不一定要使用 UUID,因为它们相当长。
该文件只需要在其目录中是唯一的。
想到的一种想法是使用File.createTempFile(String prefix, String suffix)
,但这似乎是错误的,因为该文件不是临时文件。
需要处理在同一毫秒内创建两个文件的情况。
我会使用 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);
我使用时间戳
IE
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
查看文件 javadoc,方法 createNewFile 只会在文件不存在时创建文件,并返回一个布尔值来说明文件是否已创建。
你也可以使用 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);
如果您有权访问数据库,则可以在文件名中创建和使用序列。
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";
}
结合其他答案,为什么不使用附加随机值的 ms 时间戳;重复直到没有冲突,这在实践中几乎永远不会发生。
例如:文件-ccyymmdd-hhmmss-mmm-rrrrrr.txt
我使用随机数的当前毫秒
IE
Random random=new Random();
String ext = ".jpeg";
File dir = new File("/home/pregzt");
String name = String.format("%s%s",System.currentTimeMillis(),random.nextInt(100000)+ext);
File file = new File(dir, name);
为什么不使用基于时间戳的东西..?
问题是同步。分离出冲突区域。
将文件命名为: (server-name)_(thread/process-name)_(millisecond/timestamp).(extension)
示例:aws1_t1_1447402821007.png
如何根据四舍五入到最接近毫秒的时间戳或您需要的任何精度生成...然后使用锁来同步对函数的访问。
如果您存储最后生成的文件名,您可以根据需要在其中附加连续的字母或更多数字以使其唯一。
或者,如果您更愿意在没有锁的情况下执行此操作,请使用时间步长加上线程 ID,并确保该函数花费的时间超过一毫秒,或者等待以使其执行。
看起来您有一些用于创建唯一文件名的解决方案,所以我将不理会它。我会这样测试文件名:
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;
我知道我已经来不及回答这个问题了。但我认为我应该把它放在那里,因为它似乎与其他解决方案有所不同。
我们可以连接线程名和当前时间戳作为文件名。但是这样有一个问题,比如某些线程名称包含特殊字符,如“\”,这可能会在创建文件名时产生问题。所以我们可以从线程名称中删除特殊字符,然后连接线程名称和时间戳
fileName = threadName(after removing special charater) + currentTimeStamp
为什么不使用synchronized来处理多线程。这是我的解决方案,它可以生成一个短文件名,而且它是独一无二的。
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'};
blew 是 test 的主要功能,它的工作。
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());
}
好吧,您可以使用 3-argument 版本:
File.createTempFile(String prefix, String suffix, File directory)
它可以让您将它放在您想要的位置。除非你告诉它,Java 不会将它与任何其他文件区别对待。唯一的缺点是文件名保证至少有 8 个字符长(前缀最少 3 个字符,加上函数生成的 5 个或更多字符)。如果这对你来说太长了,我想你总是可以从文件名“a”开始,然后循环“b”、“c”等,直到找到一个不存在的文件。