Je ne veux pas nécessairement utiliser les UUID car ils sont assez longs.
Le fichier doit simplement être unique dans son répertoire.
Une idée qui me vient à l’esprit est d’utiliser File.createTempFile(String prefix, String suffix)
, mais cela semble faux car le fichier n’est pas temporaire.
Le cas de deux fichiers créés dans la même milliseconde doit être traité.
Eh bien, vous pouvez utiliser la version à 3 arguments: File.createTempFile(String prefix, String suffix, File directory)
qui vous permettra de la placer où vous le souhaitez. À moins que vous ne le lui disiez, Java ne le traitera pas différemment des autres fichiers. Le seul inconvénient est que le nom du fichier est garanti avec au moins 8 caractères (minimum de 3 caractères pour le préfixe, plus 5 caractères ou plus générés par la fonction).
Si cela vous prend trop de temps, je suppose que vous pouvez toujours simplement commencer par le nom de fichier "a" et parcourir en boucle "b", "c", etc. jusqu'à ce que vous en trouviez un qui n'existe pas déjà.
J'utiliserais la bibliothèque Apache Commons Lang ( http://commons.Apache.org/lang).
Il existe une classe org.Apache.commons.lang.RandomStringUtils
qui peut être utilisée pour générer des chaînes aléatoires de longueur donnée. Très pratique non seulement pour la génération de nom de fichier!
Voici l'exemple:
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);
J'utilise l'horodatage
c'est à dire
new File( simpleDateFormat.format( new Date() ) );
Et avez le simpleDateFormat initialisé à quelque chose comme:
new SimpleDateFormat("File-ddMMyy-hhmmss.SSS.txt");
MODIFIER
Qu'en est-il de
new File(String.format("%s.%s", sdf.format( new Date() ),
random.nextInt(9)));
Sauf si le nombre de fichiers créés dans la même seconde est trop élevé.
Si c'est le cas et que le nom ne compte pas
new File( "file."+count++ );
: P
Cela fonctionne pour moi:
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());
Les noms de fichiers de sortie doivent ressembler à:
2OoBwH8OwYGKW2QE_4Sep2013061732GMT_1378275452253.Ext
Si vous avez accès à une base de données, vous pouvez créer et utiliser une séquence dans le nom du fichier.
select mySequence.nextval from dual;
Il sera garanti d'être unique et ne devrait pas devenir trop volumineux (sauf si vous extrayez une tonne de fichiers).
Regardez dans le fichier javadoc , la méthode createNewFile créera le fichier uniquement s'il n'existe pas et renverra un booléen indiquant si le fichier a été créé.
Vous pouvez également utiliser la méthode exist ():
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);
Pourquoi ne pas simplement utiliser quelque chose basé sur un horodatage ..?
En combinant d'autres réponses, pourquoi ne pas utiliser l'horodatage ms avec une valeur aléatoire ajoutée; répétez jusqu'à ce qu'il n'y ait pas de conflit, ce qui en pratique ne sera presque jamais.
Par exemple: fichier-ccyymmdd-hhmmss-mmm-rrrrrr.txt
//Generating Unique File Name
public String getFileName() {
String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(new Date());
return "PNG_" + timeStamp + "_.png";
}
Je comprends que je suis trop tard pour répondre à cette question. Mais je pense que je devrais dire ceci car il semble que quelque chose de différent d'une autre solution.
Nous pouvons concaténer threadname et timeStamp en tant que nom de fichier. Mais avec cela, il y a un problème tel qu'un nom de fil contenant un caractère spécial comme "\" qui peut créer un problème lors de la création d'un nom de fichier. Nous pouvons donc supprimer les caractères spéciaux du nom du fil, puis concaténer le nom du fil et l’horodatage.
fileName = threadName(after removing special charater) + currentTimeStamp
Cela fonctionne aussi
String logFileName = new SimpleDateFormat("yyyyMMddHHmm'.txt'").format(new Date());
logFileName = "loggerFile_" + logFileName;
Le problème est la synchronisation. Séparez les régions de conflit.
Nommez le fichier comme suit: (server-name)_(thread/process-name)_(millisecond/timestamp).(extension)
exemple: aws1_t1_1447402821007.png
On dirait que vous avez une poignée de solutions pour créer un nom de fichier unique, je vais donc le laisser tranquille. Je testerais le nom de fichier de cette façon:
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
Que diriez-vous de générer en fonction d'un horodatage arrondi à la milliseconde près, ou de la précision dont vous avez besoin ... utilisez ensuite un verrou pour synchroniser l'accès à la fonction.
Si vous stockez le dernier nom de fichier généré, vous pouvez lui ajouter des lettres séquentielles ou des chiffres supplémentaires si nécessaire pour le rendre unique.
Ou, si vous préférez le faire sans verrou, utilisez un pas de temps et un ID de thread et assurez-vous que la fonction dure plus d'une milliseconde ou attend.
Pourquoi ne pas utiliser synchronisé pour traiter plusieurs threads . Voici ma solution, elle peut générer un nom de fichier court, et il est 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 est la fonction principale du test, c’est le travail.
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());
}