Java verrouillage de fichiers et Windows - le verrou est pas « absolue »?
Question
Je suis en train de verrouiller un fichier avec Java dans un environnement Windows avec FileLock et je suis un problème: après que je verrouiller le fichier, il peut encore être consulté par d'autres processus au moins à un certain niveau.
Exemple de code suivant:
public class SimpleLockExample {
public static void main(String[] args) throws Exception {
String filename = "loremlipsum.txt";
File file = new File(filename);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
FileLock lock = null;
try {
lock = channel.tryLock();
String firstLine = raf.readLine();
System.out.println("First line of file : " + firstLine);
waitForEnter();
lock.release();
} catch (OverlappingFileLockException e) {
e.printStackTrace();
}
lock.release();
System.out.println("Lock released");
channel.close();
}
private static void waitForEnter() throws Exception {
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
reader.readLine();
reader.close();
}
}
Maintenant, quand je fermerai mon dossier avec cet exemple, il est verrouillé:
- Il ne peut pas être supprimé par Windows
- Eclipse refuse de l'ouvrir
... mais pas encore tout à fait l'épreuve des balles:
- Si je l'ouvre avec Scite (un éditeur de texte), par exemple, pas de contenu est affiché mais si je sélectionne pour enregistrer le fichier (vide comme ouvert ou avec certains écrits du contenu), il réussit et le contenu du fichier est éclairci ... (pas de contenu, il existe plus tard, même si je l'avais écrit quelque chose avec Scite)
Y at-il un moyen d'empêcher le fichier totalement d'être écrasé / effacé par d'autres processus avec Java dans Windows?
Si je comprends bien, j'utilise atm verrou exclusif. Avec verrou partagé il y a encore plus de choses qui peuvent être faites.
Ce test a été exécuté avec Windows 2000.
br, Touko
La solution
Tricky, l'API FileLock lui-même ne promet pas grand-chose:
Cette API de verrouillage de fichier est destiné à carte directement au verrouillage natif installation de l'exploitation sous-jacent système. Ainsi, les verrous détenus sur un fichier devrait être visible à tous les programmes avoir accès au dossier, quel que soit la langue dans laquelle ces programmes sont écrits.
Si oui ou non une serrure réellement empêche un autre programme de l'accès au contenu du verrouillage région dépend du système et donc non précisée. Le natif installations de certains de verrouillage de fichiers les systèmes sont purement consultatif, ce qui signifie que les programmes doivent coopérer observer un protocole de verrouillage connu dans afin de garantir l'intégrité des données. Sur d'autres systèmes de fichiers natifs serrures sont obligatoire, ce qui signifie que si un programme verrouille une région d'un fichier, puis d'autres les programmes sont effectivement empêchés de l'accès à cette région d'une manière qui serait contraire à la serrure. En d'autres encore systèmes, si les verrous de fichiers natifs sont consultatif ou obligatoire est configurable sur une base par fichier. S'assurer comportement correct et cohérent sur plates-formes, il est fortement recommandé que les verrous fournis par cette API soient utilisé comme si elles étaient les verrous consultatifs.
Bizarrement, la discussion sur l'API de verrouillage de fichier quand il est en cours de développement prétendu que système d'exploitation Windows fourni obligatoire verrouillage et sous UNIX verrouillage consultatif. Donc, à cette lecture on pourrait attendre de votre code fonctionne très bien sur Windows.
Je me demande si ce qui se passe ce que votre éditeur est pas tant la modification du fichier que la création d'un fichier temporaire, puis manipuler des entrées d'annuaire pour REPLCE la version du fichier que vous avez verrouillé avec une nouvelle version. Est-ce que Windows permettent un tel comportement?
Je me demande si vous avez besoin de recourir à JNI afin d'obtenir le niveau de contrôle dont vous avez besoin.
Autres conseils
Votre appel à .tryLock () peut retourner null si elle ne reçoit pas la serrure. De l'Javadoc:
Un objet de verrouillage représentant la serrure nouvellement acquise, ou une valeur nulle si la serrure ne peut pas être acquis en raison d'un autre programme possède un verrou de chevauchement
En outre, votre code ouvre actuellement le fichier et il tente d'acquérir un verrou. Au lieu de cela, vous devriez essayer d'obtenir la boucle de la serrure, et une fois que vous l'avez, ouvrez le fichier, lire le fichier, fermez le fichier, puis renoncer à la serrure. Et renoncer à la serrure dans une clause de finally {}
, juste au cas où votre code lance une exception avec le verrou détenu. (Jamais dû redémarrer une machine Windows simplement parce que certains fichier a été verrouillé?)