为什么我们可以在Java中更改只读文件的文件属性?

Why can we change the file attributes of a read-only file in Java?

考虑以下代码:

import java.io.IOException;
import java.nio.file.attribute.DosFileAttributeView;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
import java.time.Instant;

public class Word {
    public static void main(String[] args){

        try{
            Path path = Paths.get("readonly.txt");
            Files.createFile(path);
            DosFileAttributeView dos = Files.getFileAttributeView(path,DosFileAttributeView.class);
            dos.setReadOnly(true);

            //Files.delete(path); Access denied exception

            dos.setHidden(true);            //can change attributes all we want
            dos.setTimes(null,FileTime.from(Instant.now()),null);
            dos.setReadOnly(false);

            Files.delete(path);
        }
        catch(IOException e){
            e.printStackTrace();
        }


    }
}

自然地,尝试修改只读文件会给我们一个 AccessDeniedException。但是,如代码所示,这不适用于文件的属性,我们可以随意修改这些属性。

当然,这意味着任何人都可以轻松地将只读属性更改回 false,然后随心所欲地修改文件。

那么,为什么允许这样做,以及如何在 Java 中创建实际的只读文件?

Windows 文件的安全性由文件上的安全描述符控制。

Of course that means that anyone can easily just change the read-only attribute back to false and modify the file all they want.

不是 'anyone' - 只有获得许可(见下文)的人才能这样做。如果您创建了该文件,那么您可以为所欲为也就不足为奇了。不过一般来说,我希望其他用户(不是管理员)默认情况下无法影响您的文件。

谁可以更改 DOS 属性是通过安全描述符控制的 - 特别是通过授予或不授予 FILE_WRITE_ATTRIBUTES 访问权限。自然得有人能清除DOS只读属性,否则……一旦文件被标记为只读,就没有回头路了。通常,如果您创建一个文件,您将拥有对其的完全控制权。

给定用户或用户组是否可以将数据写入文件由访问掩码中的 FILE_WRITE_ACCESS 位(可能还有其他一些,但这是介绍性答案)控制。如果您不授予用户写权限,他们就不能写。如果你真的想阻止某人写入文件,这就是你的做法。

DOS 'read only' 属性的存在是为了兼容性,它可能有助于提示您确实不想写入此文件,但这不是安全限制。

None 这实际上与 Java 没有任何关系,它是 OS 中文件系统的工作方式。您可以使用 Windows Explorer 检查文件的安全设置。