Я работаю над процессом Java, который должен эффективно (и рекурсивно) копировать файлы/каталоги из исходного местоположения в место назначения.Копирование файлов с файловыми замками в Java
Чтобы сделать это, я хочу:
- создать замок
- , если файл назначения не существует, скопируйте его
- иначе, если файл назначения отличается, скопируйте его
- иначе они одинаковы, так что ничего не делать
- расцепления блокировки
Чтобы проверить содержимое, я планировал использовать метод Apache Commons IO FileUtils
contentsEqual(...)
. Чтобы сделать копирование, я планировал использовать метод Apache Commons IO FileUtils
copyFile(...)
.
Таким образом, код, который я придумал это (это только для файлов, каталогов обрабатываются рекурсивно до этого метода для файлов):
private static void checkAndUpdateFile(File src, File dest) throws IOException {
FileOutputStream out = new FileOutputStream(dest);
FileChannel channel = out.getChannel();
FileLock lock = channel.lock();
if (!dest.exists()) {
FileUtils.copyFile(src, out);
} else if (!FileUtils.contentEquals(src, dest)) {
FileUtils.copyFile(src, out);
}
lock.release();
channel.close();
out.close();
}
Это файл блокировки (большой), а также копии файлы (супер).
Однако, всякий раз, когда он копирует файлы, он устанавливает временную метку скопированных файлов на время копирования. Это означает, что последующие вызовы FileUtils.contentEquals(src, dest)
продолжают возвращать false
, поэтому файлы переупорядочиваются.
Что мне очень нравится, это похоже на FileUtils.copyFile(src, dest, true)
, который сохраняет временные метки файла - и это правда, если вы звоните FileUtils.contentEquals(src, dest)
. Это потребует блокировки на File
, а не FileOutputStream
, поскольку в противном случае вызов FileUtils.copyFile(src, dest, true)
завершается с ошибкой и выдает исключение, потому что файл заблокирован.
В качестве альтернативы, я рассмотрел возможность выполнения метода FileUtils.copyFile(src, dest, true)
, который должен назвать dest.setLastModified(src.lastModified())
. Однако это нужно будет вызывать после освобождения блокировки, что может вызвать проблемы, если один и тот же процесс был выполнен несколько раз одновременно.
Я также рассмотрел ид поставить замок на исходный файл, но это не помогает, как я должен поставить его на FileInputStream
, и я хочу передать File
в FileUtils.copyFile(src, dest)
.
Итак:
- Есть ли более простой способ добиться того, что я пытаюсь сделать?
- Можно ли поместить замок в файл, а не в производную от файла?
- Что было бы лучшим способом разрешить это?
- i.e. Мне просто нужно написать собственный метод подхода для части этого? (Вероятно
copyFile(...)
)
- i.e. Мне просто нужно написать собственный метод подхода для части этого? (Вероятно
Это хорошая идея, но как это работает с блокировкой файлов? Я не могу получить 'FileLock' на' ByteSource', я не могу создать ByteSource из файла, пока есть отдельный замок, и было бы бессмысленно делать «ByteSource» вне блокировки - то есть с точки зрения проблемы , это функционально эквивалентно использованию 'apache.commons.io.FileUtils' – amaidment
@amaidment, вы можете получить URL-адрес из файла http://docs.oracle.com/javase/7/docs/api/java/io/File.html # toURL% 28% 29. Как только вы заблокируете файл, получите URL-адрес и получите исходный источник байта и тот же файл назначения для – Makky
Нет, это не сработает. Когда код вызывает 'inByte.contentEquals (outByte)', он пытается получить доступ к файлу, который был заблокирован, и с ошибкой «IOException: процесс не может получить доступ к файлу, потому что другой процесс имеет заблокированную часть файла», – amaidment