我有一个写入文件的方法。我需要同步文件对象
class MessageFile{
public static final String fileName="Main.html"
@AutoWired
AppConifg appconfig;
public boolean writeToFile(String fileContent) throws Exception{
String path = appConfig.getNewsPath() + File.separator + fileName; // getNewsPath is non-static method
final File alertFile= new File(path);
FileOutputStream out = null;
synchronized (alertFile) {
if (!alertFile.exists()) {
alertFile.createNewFile();
}
try {
out = new FileOutputStream(alertFile, false);
out.write(fileContent.getBytes());
out.flush();
} finally {
if (out != null) {
out.close();
}
}
}
return true;
}
}
但是上面的代码不会对文件对象采取锁定独占锁定,因为此类的另一个实例可以锁定此类并写入文件。 所以我想如何处理这种情况? 我发现一个解决方法是创建一个附加时间戳的临时文件名(因此临时文件名将始终是唯一的),在向其写入内容之后,将首先删除原始文件,然后将临时文件重命名为原始文件名。
答案 0 :(得分:0)
如果它是唯一访问该文件的对象,您可以尝试在MessageFile.class上进行同步。
答案 1 :(得分:0)
每次运行方法时,您都在创建新的File
对象(alertFile
),因此每次运行方法时锁都不会执行任何操作 - 您需要具有静态{{1}实例在所有方法调用中共享。
如果每次运行该方法时File
可能不同,您可以创建path
实例并像这样使用它:
static Map<String, File>
,请创建它。File
实例。File
用作锁定并对其执行操作。基于修改后答案的示例:
File
答案 2 :(得分:0)
您的程序没有获得文件的独占锁定,因为您在类synchronized
的实例之间没有共享的本地变量alertFile
上使用MessageFile
(每个对象都有自己的alertFile
)。您有两种可能性来解决这个问题:
1-创建一些静态对象并在其上进行同步(您可以使用fileName
,因为它已经存在)。
2-所有对象中的引用都指向同一个对象(例如,在构造函数中传递)并在其上进行同步。
答案 3 :(得分:0)
在类级别对象上进行同步,即MessageFile.class或使用静态同步方法wrtietofile()。它将确保一次只有一个线程写入文件。它还保证一旦线程将整个数据写入文件,就会释放锁。