Каков наилучший способ создания уникального и короткого имени файла в Java



Я не обязательно хочу использовать UUIDs, так как они довольно длинные.



файл просто должен быть уникальным в пределах каталога.



одна мысль, которая приходит на ум-это использовать File.createTempFile(String prefix, String suffix), но это кажется неправильным, потому что файл не является временным.



необходимо обработать случай двух файлов, созданных за одну миллисекунду.

591   15  

15 ответов:

Ну, вы могли бы использовать версию с 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");

EDIT

А как же

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

Если у вас есть доступ к базе данных, вы можете создать и использовать последовательности в имени файла.

select mySequence.nextval from dual;

он будет гарантированно уникальным и не должен быть слишком большим (если вы не выкачиваете тонну файлов).

посмотреть файл 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);

Почему бы просто не использовать что-то на основе временных меток..?

комбинируя другие ответы, почему бы не использовать метку времени ms со случайным значением; повторяйте до тех пор, пока не возникнет конфликт, который на практике почти никогда не будет.

например: File-ccyymmdd-hhmmss-mmm-rrrrrr.txt

Как насчет генерации на основе метки времени округлены до ближайшей миллисекунды, или любой точности вам нужно... затем используйте блокировку для синхронизации доступа к функции.

Если вы сохраняете последнее сгенерированное имя файла, вы можете добавить к нему последовательные буквы или дополнительные цифры по мере необходимости, чтобы сделать его уникальным.

или если вы предпочитаете делать это без блокировок, используйте временной шаг плюс идентификатор потока и убедитесь, что функция занимает больше миллисекунды или ждет, чтобы она делает.

похоже, у вас есть несколько решений для создания уникального имени файла, поэтому я оставлю это в покое. Я бы проверил имя файла таким образом:

    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;

Я понимаю, что слишком поздно отвечать на этот вопрос. Но я думаю, что я должен поставить это, поскольку это кажется чем-то отличным от другого решения.

мы можем объединить threadname и текущую метку времени в качестве имени файла. Но с этим есть одна проблема, как некоторые имя потока содержит специальный символ, Как"\", который может создать проблему при создании имени файла. Таким образом, мы можем удалить специальный символ из имени потока, а затем объединить имя потока и штамп времени

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'};

дунул основная функция для теста, это работа.

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

}

проблема синхронизации. Отделите регионы конфликта.

имя файла : (server-name)_(thread/process-name)_(millisecond/timestamp).(extension)
пример : aws1_t1_1447402821007.png

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

Comments

    Ничего не найдено.