Каков наилучший способ создания уникального и короткого имени файла в Java
Я не обязательно хочу использовать UUIDs, так как они довольно длинные.
файл просто должен быть уникальным в пределах каталога.
одна мысль, которая приходит на ум-это использовать File.createTempFile(String prefix, String suffix), но это кажется неправильным, потому что файл не является временным.
необходимо обработать случай двух файлов, созданных за одну миллисекунду.
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