У меня есть несколько потоков, которые сериализуют мои объекты данных в файлы.Имя файла основано на 2 полях из объекта
class Data {
org.joda.DateTime time;
String title;
public String getFilename() {
return time.toString() + '_' + title + ".xml";
}
Возможно, что 2 объекта данных будут иметь одинаковое время и заголовок, и поэтому одно и то же имя файла.
Это приемлемо, и я рад за то, что спасся.(В любом случае это, вероятно, один и тот же объект данных, если они одинаковы)
Моя проблема в том, что два (или более) потока записывают в файл ОДНОВРЕМЕННО, вызывая неправильный XML.
Я посмотрел на java.nio.channels.FileLock, но он предназначен для блокировки VM-Wide и специально НЕ подходит для блокировки внутри потока.
Я мог синхронизироваться с DataIO.class (но это будетвызывать ОГРОМНЫЕ издержки, поскольку я действительно хочу синхронизировать только с отдельным файлом).
Синхронизация с объектом File будет бесполезной, поскольку несколько объектов File могут представлять один и тот же системный файл.
Код следует:
class DataIO {
public void writeArticleToFile(Article article, String filename, boolean overwrite) throws IOException {
File file = new File(filename);
writeArticleToFile(article, file, overwrite);
}
public void writeDataToFile(Data data, File file, boolean overwrite) throws IOException {
if (file.exists()) {
if (overwrite) {
if (!file.delete()) {
throw new IOException("Failed to delete the file, for overwriting: " + file);
}
} else {
throw new IOException("File " + file + " already exists, and overwrite flag is set to false.");
}
}
File parentFile = file.getParentFile();
if (parentFile != null) {
file.getParentFile().mkdirs();
}
file.createNewFile();
if (!file.canWrite()) {
throw new IOException("You do not have permission to write to the file: " + file);
}
FileOutputStream fos = new FileOutputStream(file, false);
try {
writeDataToStream(data, fos);
logger.debug("Successfully wrote Article to file: " + file.getAbsolutePath());
} finally {
fos.close();
}
}
}