Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

security

nio

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.

like image 519
Paul Taylor Avatar asked Jan 29 '16 15:01

Paul Taylor


People also ask

Which method of the class returns true if the file exists otherwise returns False?

exists() method. The idea is to use the File. exists() method to determine whether a file denoted by a specified pathname exists. This method returns true if the file exists; false otherwise.

Is exist in Java?

The exists() function is a part of the File class in Java. This function determines whether the is a file or directory denoted by the abstract filename exists or not. The function returns true if the abstract file path exists or else returns false. Parameters: This method does not accept any parameter.


2 Answers

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.

like image 119
PNS Avatar answered Oct 23 '22 01:10

PNS


Theses are two different methods: Files.exists() and path.toFile().exists().

Files.exists() defines that file denoted by this abstract pathname exists. In other words that file exists and user has READ access to it.

path.toFile().exists() indicates the file exists then there is no guarantee that a subsequence access will succeed. In other words file exist without checking that user has READ access to it.

It really depends on user which runs the program. When you work under your ID (Paul) it works fine. Especially in command line where you gan you ATTRIB command.

However, when you use some other application to run your code it depends on the system configuration. Run this ATTRIB or similar command inside your application and you will see.

I think you run some web site under IIS. This way is usually configured for lowest level user in the system with almost no rights to prevent security breaks. Usually it is everyone or NT AUTHORITY. As I can see this particular access has no rights to read your file

NT AUTHORITY\SYSTEM:READ_DATA/...:DENY

Naturally you have 2 different answers - FALSE: user which ID is used by running application cannot read this file, TRUE: file physically exist.

Change running ID for your application or grant READ access to everyone for this particular file including all directories in its path and you will have the same result in this two methods which check different meanings.

like image 42
Alex Avatar answered Oct 22 '22 23:10

Alex