如何在Java中安全地操作文件?

时间:2012-11-19 01:33:53

标签: thread-safety file-access

每次在我的网站上请求页面时,我都会通过以下服务电话记录一些详细信息:

logService.logPageRequest(session, request, contentId);

此服务调用使用静态FileUtils(我自己的)方法对文件进行实际更新。

public static void appendToTextFile(String string, String fileRootDirectory, String subdirectory, String filename, boolean startOnNewLine) throws Exception {
    // code irrelevant to the question removed

    String filePath=fileDirectory+"/"+filename;
    File file=new File(filePath);
    if(file.exists()) {
        FileWriter out = new FileWriter(filePath, true);
        if(startOnNewLine) {
            out.write("\r\n");
        }
        out.write(string);
        out.close();
     } else {
         FileWriter out = new FileWriter(filePath);
         out.write(string);
         out.close();
}

每隔一段时间(假设每15分钟安排一次),我会执行另一项重命名此文件并开始处理的服务。

我想了解如何确保并发写入是安全的,并且在写入过程中不执行重命名。我想答案将是某种形式的同步。

1 个答案:

答案 0 :(得分:2)

这两个服务需要共享一个同步对象:它可以是任何东西(甚至new byte[1])但它必须是同一个实例,并传递到您的“服务”中。只要有关键部分,这意味着代码的一部分想要在共享资源上运行,就需要将其包装在

synchronized(theInstanceOfSynchronizationObject) {
  // ... your code for critical section
}

良好锁定的规则是确定性地知道你锁定了什么,什么是共享资源。什么会杀死你(并引入死锁)是随机添加同步块,希望“解决”。在您的特定示例中,最有可能是file上的操作:只是操作,而不是对文件名字符串的操作,File的实例化:您可以有很多{{} 1}}指向磁盘上相同文件的对象,并且它不是关键操作,只要它还没有触及磁盘。所以我会说

File

同样,保护其他服务中的File file=new File(filePath); synchronized(theInstanceOfSynchronizationObject) { if(file.exists()) { } else { } } 操作。请记住,它不是您要保护的File对象,而是文件本身