Ich versuche zu prüfen, ob eine bestimmte Java.io.File von einem externen Programm geöffnet ist. Unter Windows benutze ich diesen einfachen Trick:
try {
FileOutputStream fos = new FileOutputStream(file);
// -> file was closed
} catch(IOException e) {
// -> file still open
}
Ich weiß, dass Unix-basierte Systeme das Öffnen von Dateien in mehreren Prozessen ermöglichen. Gibt es einen ähnlichen Trick, um das gleiche Ergebnis für Unix-basierte Systeme zu erzielen?
Jede Hilfe/Hack sehr geschätzt :-)
Hier ein Beispiel zur Verwendung von lsof für Unix-basierte Systeme:
public static boolean isFileClosed(File file) {
try {
Process plsof = new ProcessBuilder(new String[]{"lsof", "|", "grep", file.getAbsolutePath()}).start();
BufferedReader reader = new BufferedReader(new InputStreamReader(plsof.getInputStream()));
String line;
while((line=reader.readLine())!=null) {
if(line.contains(file.getAbsolutePath())) {
reader.close();
plsof.destroy();
return false;
}
}
} catch(Exception ex) {
// TODO: handle exception ...
}
reader.close();
plsof.destroy();
return true;
}
Hoffe das hilft.
Sie können das Java-Programm lsof
Unix ausführen, das Ihnen mitteilt, welcher Prozess eine Datei verwendet, und dann die Ausgabe analysieren. Um ein Programm aus Java-Code auszuführen, verwenden Sie beispielsweise Runtime
, Process
, ProcessBuilder
-Klassen. Hinweis: Ihr Java-Programm ist in diesem Fall nicht portierbar und widerspricht dem Konzept der Portabilität. Überlegen Sie sich also zweimal, ob Sie das wirklich brauchen :)
Dieses sollte auch für Windows-Systeme funktionieren. Aber Achtung, funktioniert nicht für Linux!
private boolean isFileClosed(File file) {
boolean closed;
Channel channel = null;
try {
channel = new RandomAccessFile(file, "rw").getChannel();
closed = true;
} catch(Exception ex) {
closed = false;
} finally {
if(channel!=null) {
try {
channel.close();
} catch (IOException ex) {
// exception handling
}
}
}
return closed;
}
Sie können diesen Semaphortypcode für eine Dateisperre von @ZZ Coder ausprobieren
File file = new File(fileName);
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
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();
}
Vielen Dank für den ursprünglichen Vorschlag. Ich habe ein kleines Upgrade, das für diese Methode etwas wichtig ist:
FileOutputStream fos = null;
try {
// Make sure that the output stream is in Append mode. Otherwise you will
// truncate your file, which probably isn't what you want to do :-)
fos = new FileOutputStream(file, true);
// -> file was closed
} catch(IOException e) {
// -> file still open
} finally {
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Prost, Gumbatron