What is the best way to generate a unique and short file name in Java

JavaFile

Java Problem Overview


I don't necessarily want to use UUIDs since they are fairly long.

The file just needs to be unique within its directory.

One thought which comes to mind is to use File.createTempFile(String prefix, String suffix), but that seems wrong because the file is not temporary.

The case of two files created in the same millisecond needs to be handled.

Java Solutions


Solution 1 - Java

Well, you could use the 3-argument version: File.createTempFile(String prefix, String suffix, File directory) which will let you put it where you'd like. Unless you tell it to, Java won't treat it differently than any other file. The only drawback is that the filename is guaranteed to be at least 8 characters long (minimum of 3 characters for the prefix, plus 5 or more characters generated by the function).

If that's too long for you, I suppose you could always just start with the filename "a", and loop through "b", "c", etc until you find one that doesn't already exist.

Solution 2 - Java

I'd use Apache Commons Lang library (http://commons.apache.org/lang">http://commons.apache.org/lang</a>;).

There is a class org.apache.commons.lang.RandomStringUtils that can be used to generate random strings of given length. Very handy not only for filename generation!

Here is the example:

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);

Solution 3 - Java

I use the timestamp

i.e

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

And have the simpleDateFormat initialized to something like as:

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

EDIT

What about

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

Unless the number of files created in the same second is too high.

If that's the case and the name doesn't matters

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

:P

Solution 4 - Java

This works for me:

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());

Output filenames should look like :

2OoBwH8OwYGKW2QE_4Sep2013061732GMT_1378275452253.Ext

Solution 5 - Java

Look at the File javadoc, the method createNewFile will create the file only if it doesn't exist, and will return a boolean to say if the file was created.

You may also use the exists() method:

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);

Solution 6 - Java

If you have access to a database, you can create and use a sequence in the file name.

select mySequence.nextval from dual;

It will be guaranteed to be unique and shouldn't get too large (unless you are pumping out a ton of files).

Solution 7 - Java

    //Generating Unique File Name
    public String getFileName() {
        String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
        return "PNG_" + timeStamp + "_.png";
    }

Solution 8 - Java

Combining other answers, why not use the ms timestamp with a random value appended; repeat until no conflict, which in practice will be almost never.

For example: File-ccyymmdd-hhmmss-mmm-rrrrrr.txt

Solution 9 - Java

I use current milliseconds with random numbers

i.e

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);

Solution 10 - Java

Why not just use something based on a timestamp..?

Solution 11 - Java

Problem is synchronization. Separate out regions of conflict.

Name the file as : (server-name)_(thread/process-name)_(millisecond/timestamp).(extension)
example : aws1_t1_1447402821007.png

Solution 12 - Java

How about generate based on time stamp rounded to the nearest millisecond, or whatever accuracy you need... then use a lock to synchronize access to the function.

If you store the last generated file name, you can append sequential letters or further digits to it as needed to make it unique.

Or if you'd rather do it without locks, use a time step plus a thread ID, and make sure that the function takes longer than a millisecond, or waits so that it does.

Solution 13 - Java

It looks like you've got a handful of solutions for creating a unique filename, so I'll leave that alone. I would test the filename this way:

    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

Solution 14 - Java

This also works

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

logFileName = "loggerFile_" + logFileName;

Solution 15 - Java

I understand that I am too late to reply on this question. But I think I should put this as it seems something different from other solution.

We can concatenate threadname and current timeStamp as file name. But with this there is one issue like some thread name contains special character like "" which can create problem in creating file name. So we can remove special charater from thread name and then concatenate thread name and time stamp

fileName = threadName(after removing special charater) + currentTimeStamp

Solution 16 - Java

Why not use synchronized to process multi thread. here is my solution,It's can generate a short file name , and it's unique.

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 is main function for test , It's work.

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());
	
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeff BloomView Question on Stackoverflow
Solution 1 - JavaPestoView Answer on Stackoverflow
Solution 2 - JavaTomasz BłachowiczView Answer on Stackoverflow
Solution 3 - JavaOscarRyzView Answer on Stackoverflow
Solution 4 - JavaMD. Mohiuddin AhmedView Answer on Stackoverflow
Solution 5 - JavapgrasView Answer on Stackoverflow
Solution 6 - JavaShaneView Answer on Stackoverflow
Solution 7 - JavaLEGEND MORTALView Answer on Stackoverflow
Solution 8 - JavaLawrence DolView Answer on Stackoverflow
Solution 9 - JavaBalaView Answer on Stackoverflow
Solution 10 - JavaGalwegianView Answer on Stackoverflow
Solution 11 - JavaSmit ThakkarView Answer on Stackoverflow
Solution 12 - JavajustinhjView Answer on Stackoverflow
Solution 13 - JavaPeter AnthonyView Answer on Stackoverflow
Solution 14 - JavaAkshay PrabhakarView Answer on Stackoverflow
Solution 15 - JavaRoshanView Answer on Stackoverflow
Solution 16 - JavaIgnoreView Answer on Stackoverflow