J'ai besoin d'écrire un fichier renommé par lots personnalisé. J'en ai fait le gros, sauf que je ne vois pas comment vérifier si un fichier est déjà ouvert. J'utilise simplement le paquetage java.io.File et il existe une méthode canWrite (), mais cela ne semble pas vérifier si le fichier est utilisé par un autre programme. Des idées sur la façon dont je peux faire ce travail?
Réponses
Trop de publicités?Utilisation de la bibliothèque Apache Commons IO ...
boolean isFileUnlocked = false;
try {
org.apache.commons.io.FileUtils.touch(yourFile);
isFileUnlocked = true;
} catch (IOException e) {
isFileUnlocked = false;
}
if(isFileUnlocked){
// Do stuff you need to do with a file that is NOT locked.
} else {
// Do stuff you need to do with a file that IS locked
}
(Le Q&A est sur la façon de traiter avec Windows "ouvrir le fichier" verrous ... pas comment mettre en oeuvre ce type de verrouillage de façon portable.)
Cette question se heurte à des problèmes de portabilité et des conditions de course:
- Vous pouvez essayer d'utiliser FileLock, mais il n'est pas nécessairement pris en charge par votre système d'exploitation et/ou de système de fichiers.
- Il apparaît que sur Windows, vous avez peut-être pas utiliser FileLock si une autre application a ouvert le fichier dans un sens particulier.
- Même si vous avez réussi à utiliser FileLock ou autre chose, vous avez encore le problème que quelque chose peut venir et ouvrir le fichier d'entre vous de tester le fichier et de faire le changement de nom.
Un moyen plus simple et (probablement) plus robuste solution est simplement d'essayer de le renommer (ou peu importe ce que vous essayez de le faire) et de diagnostiquer la valeur de retour et / ou Java exceptions qui surviennent en raison de fichiers ouverts.
Notes:
Si vous utilisez l'
Files
API au lieu de l'File
API, vous obtiendrez plus d'informations en cas de panne.Sur les systèmes où vous êtes autorisé à renommer (ou autre), un blocage ou d'ouvrir le fichier, vous n'aurez pas de panne de résultat ou à des exceptions. L'opération va réussir juste.
// TO CHECK WHETHER A FILE IS OPENED
// OR NOT (not for .txt files)
// the file we want to check
String fileName = "C:\\Text.xlsx";
File file = new File(fileName);
// try to rename the file with the same name
File sameFileName = new File(fileName);
if(file.renameTo(sameFileName)){
// if the file is renamed
System.out.println("file is closed");
}else{
// if the file didnt accept the renaming operation
System.out.println("file is opened");
}
Votre meilleur pari est de définir un verrou exclusif sur le fichier. Si le fichier est ouvert par d'autres processus, vous obtiendrez une exception. Par exemple,
File file = new File(fileName);
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
// Get an exclusive lock on the whole file
FileLock lock = channel.lock();
try {
lock = channel.tryLock();
// Ok. You get the lock
} catch (OverlappingFileLockException e) {
// File is open by someone else
} finally {
lock.release();
}
@Stephen C
Renommer n'échouerait pas sur un fichier ouvert sur la plupart des systèmes de fichiers sous Unix. Les fichiers peuvent être renommés ou supprimés d'un répertoire et les descripteurs de fichiers ouverts seront toujours valides et continueront à être utilisés pour lire et écrire dans le fichier.