【问题标题】:canWrite() not returning value as expectedcanWrite() 未按预期返回值
【发布时间】:2020-07-06 00:30:20
【问题描述】:

我正在尝试在特定目录中创建一个文件,并且在该检查目录具有写入权限之前,如果是,则创建一个文件。虽然 canWrite() 返回 true,但它在创建时给出 PermissionException。

public static void main(String[] args) {
        String downloadPath="\\\\pc.liferay.com\\lfs\\zone\\asia\\banglore";
        StringBuilder fileName=new StringBuilder();
        fileName.append(downloadPath);      
        fileName.append(File.separator);
        fileName.append("liferay-");
        fileName.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        fileName.append(".csv");
        //new File(fileName.toString());
         try {
              File destLocation = new File(downloadPath.toString());
              System.out.println("Abstract path: "+destLocation);            
              System.out.println("Write access? "+destLocation.canWrite());           
                if(destLocation.canWrite()) {
                  File destFile = new File(fileName.toString());
                  System.out.println("File path:"+destFile.getPath()); 
                  if (destFile.createNewFile()) {
                    System.out.println("File created: " + destFile.getPath());
                  } else {
                    System.out.println("File already exists.");
                  }
                }
            } catch (IOException e) {
              System.out.println("An error occurred.");
              e.printStackTrace();
            }
        System.out.println("Done");
    }

输出:

java.io.IOException: Access is denied
    at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)
    at com.local.file.downloader.PermissionExcpetionTH.main(PermissionExcpetionTH.java:29)

【问题讨论】:

  • 您使用的是什么版本的 Windows?

标签: java file-permissions


【解决方案1】:

我相信这是一个 Java 错误/功能。如果您搜索Java Bugs database,就会发现许多关于canWrite()canRead() 在Windows 系统上的行为不一致的错误报告。

基本问题是,当 Microsoft 将 NTFS 文件系统支持添加到 Win32 库时,他们忽略了“教”访问检查调用以了解 NTFS ACLS。相反,旧调用仍仅根据 MSDOS 权限报告读/写能力。添加了新的 API 方法来处理 NTFS 文件系统访问检查,但需要更改应用程序代码(在本例中为 JVM)才能使用它们。

从 Java 错误报告来看,当 Sun Java 团队发现这个错误功能破坏了 WindowsNT 上的 Java 时,他们的反应是(正确地)说“这是一个 Windows 错误”。但微软没有修复它。对于 Sun 工程师来说,将这种变通方法应用于 Java 本地实现很快就为时已晚。最终结果是File.canRead()File.canWrite() 在某些情况下可能会在 Windows 上给出不正确的结果。

相关的 Java 错误已标记为 WontFix。


那么解决办法是什么?

一种解决方案是改用Files.isReadable()Files.isWritable()。我的理解是,他们在Files 中修复的(许多)事情之一是File.canRead()File.canWrite() 方法的异常行为。

但是,我的建议是不要费心去测试文件是否存在、是否可读或是否可写。只需尝试执行文件操作并处理异常。这样做有以下优点:

  • 它避免了必须处理访问控制中的不一致。 (例如,当您使用 SE-Linux 时,Linux 中存在不一致。文件访问可以被 SE-Linux 阻止,尽管文件权限位和 ACL 允许。)

  • 它避免了其他东西(另一个线程或另一个程序)在错误的时间更改文件系统权限的竞争条件。

还建议改用较新的java.nio.*.* API,而不是旧的File 类。较新的 API 可提供更好的诊断。

【讨论】:

    【解决方案2】:
     * @param      file   the system-dependent filename.
     * @exception  SecurityException  if the calling thread does not
     *             have permission to access the specified file.
     * @exception  NullPointerException if the file argument is null.
     * @see        #checkPermission(java.security.Permission) checkPermission
     */
     public void checkWrite(String file) {
         checkPermission(new FilePermission(file,
             SecurityConstants.FILE_WRITE_ACTION));
     }
    

    所以你没有写入文件的权限。您可以通过 2 种方式更改此权限。

    1. 通过使用命令提示符 (Windows) 或终端(Linux 或 Mac)
    2. 您可以轻松使用 file.setWriteable(true)
      *如果true,设置访问权限允许写操作;如果false 禁止写操作。

    此外,如果您不想更改访问权限并且如果您不想在没有权限的情况下写入此路径。您可以捕获错误,并且可以根据需要创建一个新文件。如果你选择这种方式,下一段代码可以帮助你一点。

        try {
            boolean canWrite = destLocation.canWrite();
        }catch (SecurityException ex){
            //Do what you need here.
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-05
      • 2017-03-31
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 2013-09-04
      • 2016-02-13
      相关资源
      最近更新 更多