Search code examples
javasecuritynio

Files.exists(path) and path.toFile().exists() give different results for the same file


I'm getting a different result for Files.exists(path) to path.toFile().exists() for a local file on Windows. I can see this file in Windows Explorer although I have (randomly) modified permissions and perhaps the permissions do not make sense.

However this doesn't explain why the old method returns true and the new methods returns false. The file definently exists but maybe it is invisible to the user running the Java code, so I'm not sure what the correct answer should be. Nor can I see how to see which user is running the code, there is only one real user Paul on the computer, but I'm wondering if whether if run as administrator or not effects things.

System.out.println("Path Exists(1):"+Files.exists(path));
System.out.println("Path Exist(2) :"+path.toFile().exists());

gives

Path Exists(1):false
Path Exist(2) :true

Also

System.out.println("Path readable(3) :"+Files.isReadable(path));
System.out.println("Path readable(4):"+path.toFile().canRead());

works in same way giving

Path readable(3) :false
Path readable(4):true

Permissions output

File C:\Code\jthink\opensrc\jaudiotagger\testdata\test157.dsf permissions
owner:PCLAPTOP\Paul
NT AUTHORITY\SYSTEM:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:DENY
BUILTIN\Administrators:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:DENY
BUILTIN\Administrators:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:ALLOW
NT AUTHORITY\SYSTEM:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE:ALLOW
BUILTIN\Users:READ_DATA/READ_NAMED_ATTRS/EXECUTE/READ_ATTRIBUTES/READ_ACL/SYNCHRONIZE:ALLOW
NT AUTHORITY\Authenticated Users:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/SYNCHRONIZE:ALLOW


c:\Code\jthink\opensrc\jaudiotagger>attrib C:\Code\jthink\opensrc\jaudiotagger\testdata\test157.dsf
A    R       C:\Code\jthink\opensrc\jaudiotagger\testdata\test157.dsf

Update I dont have a conclusion but thought this information could be useful.

I was running code in IntelliJ IDE without the IDE Run program as Administrator option enabled, enabling this did then cause the Java application to also get the administrator privileges.

Interesting for another file I didn't add any DENY privileges, I just disabled inherit permissions and remove READ permissions from all groups. Then when I ran as user without run as admin enabled it could not read the file and also this code could not any output any information

AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
if (view != null)
{
    sb.append("Owner:"+view.getOwner().getName()+"**");
    for (AclEntry acl : view.getAcl())
    {
        sb.append(acl.principal()+"**");
        for(AclEntryPermission aep:acl.permissions())
        {
            sb.append(aep.toString() + "**");
        }
    }
}

but when I run with Run program as adminstrator enabled it still couldnt read the file, but the above code did now output some of the permissions as follows:

Owner:BUILTIN\Administrators

NT AUTHORITY\SYSTEM:WRITE_DATA/APPEND_DATA/WRITE_NAMED_ATTRS/WRITE_ATTRIBUTES/SYNCHRONIZE:ALLOW PCLAPTOP\Paul:WRITE_DATA/APPEND_DATA/WRITE_NAMED_ATTRS/WRITE_ATTRIBUTES/SYNCHRONIZE:ALLOW BUILTIN\Administrators:WRITE_DATA/APPEND_DATA/WRITE_NAMED_ATTRS/WRITE_ATTRIBUTES/SYNCHRONIZE:ALLOW

as you can see even though Administrators do not have READ or READ PERMISSIONS options they can output the permissions whereas before they couldn't, perhaps due to BUILTIN/Administraor being returned as owner.


Solution

  • Try reading this: https://docs.oracle.com/javase/tutorial/essential/io/check.html

    It states that, Files.exists(path) returning false does not mean that it does not exist, so yeah it would seem there is a permission problem. Try the Files.notExists(path) as well and see what it returns. If it is false it means that it can not be determined whether the file exists, but if it returns true, there is probably some problem in your code.

    Try running your file from the command line instead of netbeans. If you don't know how to do this you can just search google, there is tons of stuff on this, but basically what you want to do is to compile the .java file with javac myfile.java and then run it with java myfile. Do this with a normal command prompt and one you open as administrator and see what you get.