Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

Ну, вы можете использовать версию с тремя аргументами: File.createTempFile(String prefix, String suffix, File directory) который позволит вам разместить его там, где вы хотите. Если вы не скажете это, Java не будет обрабатывать это иначе, чем любой другой файл. Единственным недостатком является то, что имя файла гарантированно должно быть длиной не менее 8 символов (минимум 3 символа для префикса плюс 5 или более символов, сгенерированных функцией).

Если это слишком долго для вас, я полагаю, вы всегда можете просто начать с имени файла "a" и переходить к "b", "c" и т.д., Пока не найдете тот, который еще не существует.

Ответ 2

Я бы использовал библиотеку 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);

Ответ 3

Я использую отметку времени

то есть

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

: р

Ответ 4

Это работает для меня:

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

Ответ 5

Посмотрите Файл 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);

Ответ 6

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

select mySequence.nextval from dual;

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

Ответ 7

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

Ответ 8

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

Например: Файл-ccyymmdd-hhmmss-mmm-rrrrrr.txt

Ответ 9

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

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

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

Ответ 10

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

    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

Ответ 11

Это также работает

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

logFileName = "loggerFile_" + logFileName;

Ответ 12

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

Мы можем объединить имя_потока и текущий timeStamp в качестве имени файла. Но с этим существует одна проблема, например, какое-то имя потока содержит специальный символ типа "\", который может создать проблему при создании имени файла. Поэтому мы можем удалить специальный charater из имени потока, а затем объединить имя потока и отметку времени

fileName = threadName(after removing special charater) + currentTimeStamp

Ответ 13

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

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

bleup - основная функция теста, он работает.

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

}

Ответ 14

Проблема в синхронизации. Выделите районы конфликта.

Назовите файл как: (server-name)_(thread/process-name)_(millisecond/timestamp).(extension)
пример: aws1_t1_1447402821007.png

Ответ 15

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