Mach es einfach (und räum nach dir auf)
Ein möglicher Ansatz könnte darin bestehen, die Datei zu erstellen und sie schließlich zu löschen, wenn die Erstellung erfolgreich war. Ich hoffe jedoch, dass es eine elegantere Möglichkeit gibt, dasselbe Ergebnis zu erzielen.
Vielleicht ist das der robusteste Weg.
Im Folgenden wird canCreateOrIsWritable
festgelegt, ob Ihr Programm eine Datei und ihre übergeordneten Verzeichnisse unter einem bestimmten Pfad erstellen oder, falls dort bereits eine Datei vorhanden ist, in diese Datei schreiben kann.
Dazu werden die erforderlichen übergeordneten Verzeichnisse sowie eine leere Datei im Pfad erstellt. Danach werden sie gelöscht (wenn eine Datei im Pfad vorhanden war, wird sie in Ruhe gelassen).
So können Sie es verwenden:
var myFile = new File("/home/me/maybe/write/here.log")
if (canCreateOrIsWritable(myFile)) {
createParents(myFile);
appendOrCreate(myFile, "new content");
} else {
var tempDir = System.getProperty("java.io.tmpdir");
var alternative = Paths.get(tempDir, "second_choice.log");
appendOrCreate(alternative, "new content in temporary directory");
}
Die wesentliche Methode mit ein paar Hilfsmethoden:
static boolean canCreateOrIsWritable(File file) {
boolean canCreateOrIsWritable;
List<File> parentDirsToCreate = getParentDirsToCreate(file);
reverse(parentDirsToCreate).forEach(File::mkdir);
try {
boolean wasCreated = file.createNewFile();
if (wasCreated) {
canCreateOrIsWritable = true;
file.delete();
parentDirsToCreate.forEach(File::delete);
} else {
canCreateOrIsWritable = java.nio.file.Files.isWritable(file.toPath());
}
} catch (IOException e) {
canCreateOrIsWritable = false;
}
return canCreateOrIsWritable;
}
static List<File> getParentDirsToCreate(File file) {
var parentsToCreate = new ArrayList<File>();
File parent = file.getParentFile();
while (parent != null && !parent.exists()) {
parentsToCreate.add(parent);
parent = parent.getParentFile();
}
return parentsToCreate;
}
static <T> List<T> reverse(List<T> input) {
var reversed = new ArrayList<T>();
for (int i = input.size() - 1; i >= 0; i--) {
reversed.add(input.get(i));
}
return reversed;
}
static void createParents(File file) {
File parent = file.getParentFile();
if (parent != null) {
parent.mkdirs();
}
}
Beachten Sie, dass sich zwischen dem Aufrufen canCreateOrIsWritable
und Erstellen der eigentlichen Datei möglicherweise der Inhalt und die Berechtigungen Ihres Dateisystems geändert haben.