Reputation: 254
I found the same question 7 years ago, but cannot find a solution.
I create a file "readonlyfile.txt" with denied write permission. Windows does not allow
to edit and store this file - ok- expected.
However the following canWrite() code says that this file can be written.
Path readonlyfile = Paths.get("C:\\temp_\\__readonlyfile.txt");
boolean canwrite = false;
try
{ File f = readonlyfile.toFile();
//File f = new File("C:/temp_/__readonlyfile.txt");
//File f = new File("C:\\temp_\\__readonlyfile.txt");
canwrite = f.canWrite();
} catch (Exception e)
{ System.out.println("canWrite()" + e);
}
System.out.println("---canWrite: " + canwrite);
//---canWrite: true
BufferedWriter bw = null;
try
{
bw = Files.newBufferedWriter(readonlyfile);
bw.write("foo");
System.out.println("write() succeeds");
} catch (Exception e)
{ System.out.println("---cannot open: " + e);
//---cannot open: java.nio.file.AccessDeniedException: C:\temp_\__readonlyfile.txt
} finally
{ try { bw.close(); } catch (Exception ee) {}
}
Upvotes: 3
Views: 635
Reputation: 254
Thanks boot-and-bonnet: Files.isWritable() is more reliable than File.canWrite() however returns always false if a file does not exist. So I create some code 'isWritable() in MyFile class (see below) to overcome this problem. Test code is:
canwrite = MyFile.isWritable(readonlyfile);
System.out.println("canWrite: " + canwrite + " : " + readonlyfile);
canwrite = MyFile.isWritable(notexists);
System.out.println("canWrite: " + canwrite + " : " + notexists);
canwrite = MyFile.isWritable(readonlydir);
System.out.println("canWrite: " + canwrite + " : " + readonlydir);
canwrite = MyFile.isWritable(dir); // existing dir
System.out.println("canWrite: " + canwrite + " : " + dir);
// canWrite: false : C:\temp_\__readonlyfile.txt
// canWrite: true : C:\temp_\~~~notexists.txt
// canWrite: false : C:\temp_\read-only_dir
// canWrite: true : C:\temp_
/**
* Similar to Files.isWritable() - however also works for a non-existing file/directory.
* In this case, the creating of 'path' as a file is simulated to check write access.
* Note: Files.isWritable() mistakenly returns false for a non-existing file.
* @param path The file or directory to be examined
* @return true if the caller has write permission to the existing file/directory or could create this non-existing
* 'path' as a file, false otherwise
*/
public static boolean isWritable(Path path)
{
if (path == null) return false;
try
{
if (!Files.exists(path))
{ try
{ Files.createFile(path); //atomic
try { Files.delete(path); } catch (Exception e) {}
return true;
} catch (AccessDeniedException e)
{ return false;
} catch (Exception e)
{ logger.log(Level.INFO,"Files.createFile({0}): {1}",new Object[] {path,e}); } // let isWritable() decide
}
return Files.isWritable(path); // works fine for an existing directory too, e.g. read-only-dir
} catch (Exception e)
{ logger.log(Level.WARNING,"MyFile.isWritable(): {0}",e.toString());
}
return false;
} //--------- end of isWritable()
Upvotes: 1