2

我正在编写一个应用程序(用于教育目的),它需要使用数据库管理系统(我自己编写了极其原始的 DBMS,这是任务的一部分)。而且我想确保在我的应用程序运行的任何时候,所有表的内容都是正确的。为此,我编写了方法,它查看每个文件并进行必要的检查。问题是我只想在应用程序启动并拒绝访问文件时调用此方法一次,以确保在我的程序运行时没有人更改其内容。

我使用以下方法。当应用程序启动时,我初始化InputStreamReaderOutputStreamWriter,存储它们并仅在我的应用程序终止时关闭它们。

部分初始化方法:

FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file, true); 
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");

this.tables.get(table).put("fis", fis);
this.tables.get(table).put("fos", fos);
this.tables.get(table).put("isr", isr);
this.tables.get(table).put("osw", osw);

关闭方法:

try {
    for(Map<String, Object> table_map: tables.values()) {
        OutputStreamWriter osw = (OutputStreamWriter)table_map.get("osw"); 
        InputStreamReader isr = (InputStreamReader)table_map.get("isr"); 

        if (osw != null)
            osw.close();
        if (isr != null)
            isr.close();
    }
}
catch (IOException e) {
    throw new DBException("Closing error");
}

部分地,这种方法有效,因为当我尝试使用 MS 记事本修改这些文件中的任何一个时,我收到以下错误

“该进程无法访问该文件,因为它正被另一个进程使用”

这就是我想看到的。但是如果我使用 Notepad++,我可以在我的应用程序运行时进行任何修改,这不是我期望看到的。那么我能做些什么来确保没有其他进程可以修改我的文件呢?

我尝试使用FileLock,但如果我没记错的话,它只会拒绝我的进程的访问。

对不起我的英语不好,希望你能理解我的问题。

4

2 回答 2

2

我不确定这是一个值得解决的问题。无论您采取何种方法,具有正确权限的人都可能会撤消您的文件保护,并且无论如何都可以进行更改。

最好专注于优雅地处理无效数据,否则信任文件中的内容。添加某种完整性检查(每行或表)将使某人更难意外或恶意更改您的数据,使其看起来“有效”。

于 2012-11-04T09:02:33.297 回答
2

如果您阅读文档中的“平台依赖项”部分,您java.nio.channels.FileLock会看到:

  • FileLocks不是(仅)用于锁定在一个JVM 内部,而是用于计算机上的所有进程。
  • 文件锁(注意不同的拼写)很大程度上取决于平台和配置。

所以你基本上必须问自己:我真正需要什么保护?

如果您只想防止在同一数据上多次运行您的程序,您可以假设您的程序“表现良好”并且

  • 使用FileLocks
  • 使用标记锁定文件或
  • 在文件中使用“脏/锁定”标记

如果你想保护所有其他程序,那么你就迷失了,就像你在 Notepad++ 场景中看到的那样:考虑所有平台和所有可能的方法来规避锁和使用 Java——你没有机会。

于 2012-11-04T09:40:09.000 回答