0

I have a problem.

I have a file named for example abc. While working on this file I'll get some others files, which will have some unique info like tags or some values. I want to name them abc#unique_id. It's like a perfect/injective hash function. I can't use a normal hash function, because I can get a collision of hashes. I was thinking about generating a random number and checking if file named so exists, if yes then generate another number. But this can be less efficient if there will be more files.

Z-DNA
  • 133
  • 1
  • 10

3 Answers3

2

You can use File.createTempFile(String prefix, String suffix, File directory). From the javadoc:

Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name. If this method returns successfully then it is guaranteed that:

  • The file denoted by the returned abstract pathname did not exist before this method was invoked, and

  • Neither this method nor any of its variants will return the same abstract pathname again in the current invocation of the virtual machine.

In your case, you want to do something like this:

File newFile = File.createTempFile("abc#", ".ext", new File("/path/to/your/directory/"));
// use newFile
Community
  • 1
  • 1
Florent Bayle
  • 11,520
  • 4
  • 34
  • 47
0

Consider adding the current time/date to the end of the filename. System.currentTimeMillis(); will get the current time as a Long, and it is likely that you get more than 1 file at the exact same time (down to the millisecond).

More info here

McNultyyy
  • 992
  • 7
  • 12
  • I was thinking about it, but this is not thread-save. I mean, what if two threads will make file at the same time? (Is that even possible?) – Z-DNA Sep 07 '15 at 12:56
  • Create (thread safe) Singleton class that is responsible for creating the filenames and simply add the `syncronized` modifier to the method name (similarly to Davide's answer) and you should be fine. – McNultyyy Sep 07 '15 at 13:15
0

You can also use a counter. Here a simple example of a class using it. Note that getName is synchronized to grant the correct value of counter variable also in a multithread environment.

public class FileHelper {
    private static int counter = 0;

    static {
        init();
    }

    private static init() {
       // load last counter value from database, 
       // scanning files in the directory or saving it to a property file.
    }

    public static synchronized String getName() {
        counter++;
        return "name_" + counter;
    }
}

If it is necessary to store last counter used it is possible to add an init function to load last used counter for example from a database, or scanning the directory of created files, or saving it to a property file.

Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56
  • Yeah, but this will not survive server shutdown. After restarting program it shouldn't make collisions either – Z-DNA Sep 07 '15 at 12:54