java - File.canWrite() 没有按预期工作
问题描述
我在 7 年前发现了同样的问题,但找不到解决方案。
我创建了一个拒绝写入权限的文件“readonlyfile.txt”。Windows 不允许编辑和存储此文件 - 好的 - 预期。
然而,下面的 canWrite() 代码表明这个文件可以被写入。
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) {}
}
解决方案
感谢 boot-and-bonnet: Files.isWritable() 比 File.canWrite() 更可靠,但是如果文件不存在,则始终返回 false。所以我在 MyFile 类(见下文)中创建了一些代码 'isWritable() 来克服这个问题。测试代码为:
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()
推荐阅读
- r - 由于奇点,未定义 glm 中的随机因子
- sql - 我有 3 列,总计数、通过计数和失败计数,如果失败计数 > 8% 其开发错误,我如何在 SQL 或 SPL 中编写公式
- python - 无法为形状为 (3, 1267618) 且数据类型为 float64 的数组分配 29.0 MiB
- c# - 如何在 C# 中调用方法?
- angular - 如何将 Hyperledger Fabric 智能合约链接到前端?
- laravel - Laravel Eloquent 方法中的连接表
- identityserver4 - 未设置对象引用 主视图中的错误 - MVC 客户端快速入门
- java - JavaSE-11 的无效运行时:路径指向丢失或无法访问的文件夹
- bash - Bash 如何在列表中的特定字符串匹配条件处开始迭代
- java - 为什么paintComponent方法会执行多次?