代码之家  ›  专栏  ›  技术社区  ›  shashi

File.canWrite和Files.isWritable在Linux上未提供正确的值

  •  5
  • shashi  · 技术社区  · 10 年前

    我有一个测试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的建议将PosixFileAttributes用于类UNIX平台。工作代码如下:

    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;
    }
    
    1 回复  |  直到 10 年前
        1
  •  3
  •   Matteo    10 年前

    以正常用户的身份执行程序 false 在这两种情况下,您都无法 /root 目录

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

    $ 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