Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java File.canWrite和Files.isWritable在Linux上没有给出正确的值_Java_File_File Permissions - Fatal编程技术网

Java File.canWrite和Files.isWritable在Linux上没有给出正确的值

Java File.canWrite和Files.isWritable在Linux上没有给出正确的值,java,file,file-permissions,Java,File,File Permissions,我有一个测试java程序 import java.io.File; import java.nio.file.FileSystems; import java.nio.file.Files; public class TestFileReadOnly { public static void main(String[] args) { String filePath = args[0]; File f = new File(filePat

我有一个测试java程序

import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Files;

public class TestFileReadOnly
{    
    public static void main(String[] args)
    {
        String filePath = args[0];
        File f = new File(filePath);

        System.out.println("File.canWrite() for file: " + filePath + ", is: " + f.canWrite());
        System.out.println("Files.isWritable() for file: " + filePath + ", is: " + Files.isWritable(FileSystems.getDefault().getPath(f.getParent(), f.getName())));
    }
}  
我使用root登录Linux并创建两个文件

echo "test file" > /root/ro.txt
echo "test file" > /root/rw.txt
chmod 444 /root/ro.txt
chmod 777 /root/rw.txt
当我以这种方式执行测试程序时,输出总是不正确的

[root@xxx ~]# /jdk1.8.0_31/bin/java TestFileReadOnly /root/ro.txt
File.canWrite() for file: /root/ro.txt, is: true
Files.isWritable() for file: /root/ro.txt, is: true
[root@xxx ~]# /jdk1.8.0_31/bin/java TestFileReadOnly /root/rw.txt
File.canWrite() for file: /root/rw.txt, is: true
Files.isWritable() for file: /root/rw.txt, is: true
我基本上是在寻找java代码来验证文件是否是只读的,但无法使用上面的方法实现它。但是,这在Windows上运行良好。我尝试使用jdk1.7.0_07、jdk1.7.0_75和jdk1.8.0_31编译和执行,但结果相同。非常感谢为解决这一问题提供的任何帮助

解决方案: 使用@Matteo的建议,在类UNIX平台上使用PosixFileAttributes。工作代码如下所示:

private boolean isFileReadOnly(File file)
{
    boolean isReadOnly = false;
    if (System.getProperty("os.name").startsWith("Windows"))
    {
        // All Windows versions
        isReadOnly = !file.canWrite();
    }
    else
    {
        // All Unix-like OSes.
        Path path = Paths.get(file.getParent(), file.getName());
        PosixFileAttributes attributes = null;
        try
        {
            attributes = Files.getFileAttributeView(path, PosixFileAttributeView.class).readAttributes();
        }
        catch (java.io.IOException e)
        {
            // File presence is guaranteed. Ignore
            e.printStackTrace();
        }

        if (attributes != null)
        {
            // A file is read-only in Linux only when it has 0444 permissions.
            Set<PosixFilePermission> permissions = attributes.permissions();

            if (!permissions.contains(PosixFilePermission.OWNER_WRITE)
                && !permissions.contains(PosixFilePermission.OWNER_EXECUTE)
                && !permissions.contains(PosixFilePermission.GROUP_WRITE)
                && !permissions.contains(PosixFilePermission.GROUP_EXECUTE)
                && !permissions.contains(PosixFilePermission.OTHERS_WRITE)
                && !permissions.contains(PosixFilePermission.OTHERS_EXECUTE))
            {
                isReadOnly = true;
            }
        }
    }
    return isReadOnly;
}
private boolean isFileReadOnly(文件)
{
布尔值isReadOnly=false;
if(System.getProperty(“os.name”).startsWith(“Windows”))
{
//所有Windows版本
isReadOnly=!file.canWrite();
}
其他的
{
//所有的Unix都像操作系统。
Path Path=Path.get(file.getParent(),file.getName());
PosixFileAttributes=null;
尝试
{
attributes=Files.getFileAttributeView(路径,PosixFileAttributeView.class).readAttributes();
}
捕获(java.io.ioe异常)
{
//保证文件存在。忽略
e、 printStackTrace();
}
如果(属性!=null)
{
//在Linux中,文件只有在具有0444权限时才是只读的。
设置权限=attributes.permissions();
如果(!permissions.contains(PosixFilePermission.OWNER\u WRITE)
&&!permissions.contains(PosixFilePermission.OWNER\u EXECUTE)
&&!permissions.contains(PosixFilePermission.GROUP_WRITE)
&&!permissions.contains(PosixFilePermission.GROUP_EXECUTE)
&&!permissions.contains(PosixFilePermission.OTHERS_WRITE)
&&!permissions.contains(PosixFilePermission.OTHERS_EXECUTE))
{
isReadOnly=true;
}
}
}
返回为只读;
}

以普通用户身份执行程序时,由于无法访问
/root
目录,在这两种情况下,您都会得到
false

root
身份执行程序时,在这两种情况下都会得到
true
,因为
root
即使没有写入权限也可以写入文件:

$ echo uuu > ro.txt 
$ echo > ro.txt 
$ ls -l ro.txt 
-r--r--r-- 1 root root 1 Feb  6 15:03 ro.txt
$ cat ro.txt 

$ echo Test > ro.txt 
$ cat ro.txt 
Test

运行java的用户是否有权查看这些文件夹?如果他们无法访问这些文件夹,我认为他们无法访问这些文件。除非您是
root
,否则您无法访问
/root
。请将这些文件放入主文件夹
~/anysubfolder
,然后在x86\u 64平台上的Red Hat Linux 6.4上再次尝试以root身份登录和执行。如果可以的话,有人可以在他们的系统上试用吗?我相信root可以绕过UNIX权限并写入只读文件。您应该以普通用户的身份运行java程序。我刚刚以root用户身份在我的机器上进行了测试,并按预期工作。你能把ls-ld/root/[root@xxx~]#ls-ld/root/dr-xr-x--。33 root root 4096 Feb 6 18:57/root/Java中是否有任何方法可以仅基于文件上设置的权限返回结果,而不考虑基于所有者和登录用户的有效功能?是否有其他API可以实现这一点?您可以使用,但它只能在POSIX系统上工作。当canWrite()在Windows上工作时,我使用PosixFileAttributes方法来实现类似UNIX的平台(我想要的平台-AIX、HP-UX和Solaris都完全符合POSIX)。工作方法如下所示: