Just do it (and take it away)
A possible approach would be to try to create a file and, ultimately, delete it if the creation was successful, but I hope there is a more elegant way to achieve the same result.
Maybe this is the most reliable way.
The following is a canCreateOrIsWritable which determines whether your program can create a file and its parent directories at a given path or, if the file already exists there, write to it.
This is achieved by creating the necessary parent directories, as well as an empty file along the way. After that, he deletes them (if there was a file along the path, he remains alone).
Here is how you can use this:
var myFile = new File("/home/me/maybe/write/here.log") if (canCreateOrIsWritable(myFile)) {
The main method with several helper methods:
static boolean canCreateOrIsWritable(File file) { boolean canCreateOrIsWritable; // The non-existent ancestor directories of the file. // The file parent directory is first List<File> parentDirsToCreate = getParentDirsToCreate(file); // Create the parent directories that don't exist, starting with the one // highest up in the file system hierarchy (closest to root, farthest // away from the file) reverse(parentDirsToCreate).forEach(File::mkdir); try { boolean wasCreated = file.createNewFile(); if (wasCreated) { canCreateOrIsWritable = true; // Remove the file and its parent dirs that didn't exist before file.delete(); parentDirsToCreate.forEach(File::delete); } else { // There was already a file at the path β Let see if we can // write to it canCreateOrIsWritable = java.nio.file.Files.isWritable(file.toPath()); } } catch (IOException e) { // File creation failed 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(); } }
Remember that between calling canCreateOrIsWritable and creating the actual file, the contents and permissions of your file system may have changed.
Matthias Braun May 01 '19 at 15:30 2019-05-01 15:30
source share