Java canWrite()未按预期返回值

Java canWrite()未按预期返回值,java,file-permissions,Java,File Permissions,我正在尝试在特定目录中创建一个文件,在此之前,检查目录是否具有写访问权限,如果是,则创建一个文件。虽然canWrite()返回true,但它在创建时提供PermissionException public static void main(String[] args) { String downloadPath="\\\\pc.liferay.com\\lfs\\zone\\asia\\banglore"; StringBuilder fileName=new S

我正在尝试在特定目录中创建一个文件,在此之前,检查目录是否具有写访问权限,如果是,则创建一个文件。虽然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)或终端(Linux或Mac)
  • 您可以轻松使用file.setWriteable(true)
    *如果
    true
    ,则设置允许写操作的访问权限;如果
    false
    ,则禁止写入操作
  • 此外,如果您不想更改访问权限,如果您不想在没有权限的情况下写入此路径,请执行以下操作。您可以捕获错误,并根据需要创建新文件。如果您选择这种方式,下一个代码段可以对您有所帮助

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

    我认为这是一个Java错误/特性。如果搜索,则会出现大量有关Windows系统上
    canWrite()
    canRead()
    的不一致行为的错误报告

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

    从Java bug报告来看,当Sun Java团队发现这个错误功能破坏了WindowsNT上的Java时,他们的反应是(正确地)说“这是一个Windows bug”。但微软并没有解决这个问题。对于Sun工程师来说,将解决方案应用于Java本机实现已经太迟了。最终的结果是,在某些情况下,
    File.canRead()
    File.canWrite()
    可能会在Windows上给出不正确的结果

    相关的Java bug已标记为WontFix


    那么解决方案是什么呢

    一种解决方案是使用
    文件.isReadable()
    文件.isWritable()
    。我的理解是,他们在
    文件中修复的(许多)问题之一是
    File.canRead()和
    File.canWrite()方法的异常行为

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

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

    • 它避免了其他程序(另一个线程或另一个程序)在错误的时间更改文件系统权限的争用情况


    还建议切换到使用较新的
    java.nio.*.
    API,而不是旧的
    文件
    类。较新的API提供了更好的诊断功能。

    您使用的是什么版本的Windows?
        try {
            boolean canWrite = destLocation.canWrite();
        }catch (SecurityException ex){
            //Do what you need here.
        }