У меня есть несколько процессов на разных компьютерах, которые необходимы для чтения/записи в общий файл XML, для этого я использую DOM with Java
и FileLocks
(Хотя я знаю, что база данных будет более эффективным подходом , это небезопасно из-за ограничений проекта).Одновременно пишите в файл XML
Чтобы внести изменения в файл XML, соответствующий процесс сначала создает исключительно заблокированный канал, который используется для чтения файла, затем он пытается повторно использовать один и тот же канал для записи новой версии перед закрытием канала; таким образом, замок никогда не падает. Однако проблема заключается в том, что я получаю java.nio.channels.ClosedChannelException
при попытке записать результат, хотя я никогда не закрываю канал напрямую. У меня есть подозрения, что строка кода:
doc = dBuilder.parse(Channels.newInputStream(channel));
закрывает канал. Если да, то как я могу заставить канал оставаться открытым? Мой код можно увидеть ниже:
[удален код после обновления]
UPDATE: Размещение System.out.println(channel.isOpen())
до и после подозрительного строки кода подтверждает, что это, где канал закрыт.
ОБНОВЛЕНИЕ: После запроса separate question приведенный ниже код предотвращает закрытие канала во время операции синтаксического анализа. Проблема заключается в том, что вместо замены исходного XML-файла трансформатор добавляет измененный документ в оригинал. В документации я не могу найти никаких связанных опций для указания вывода Transformer.transform
(я искал Transformer
/Transformer factory
/StreamResult
). Я что-то упускаю? Нужно ли мне как-то очистить канал перед тем, как писать? Благодарю.
ОБНОВЛЕНИЕ: Наконец-то решена проблема с добавлением, обрезая канал до размера 0. Спасибо @JLRishe за совет. Выложили рабочий код в качестве ответа.
Привет, Аарон, это звучит как лучшее решение, и я могу заглянуть в будущее. Пока, хотя проект довольно небольшой, поэтому я бы предпочел заставить его работать так, как есть. – Hungry
Попробуйте перемотать канал после прочтения.Или попробуйте придумать небольшой тестовый пример, где вы просто читаете простую строку; для вашего теста нет необходимости добавлять сложность, которую приносит XML. Если малый тест работает, то в «DocumentBuilderFactory» есть ошибка/проблема, или, может быть, возвращаемый 'InputStream' имеет метод' finalize() '. –
Приветствия, обновили вопрос на основе вашего ответа. – Hungry