2015-02-28 3 views
3

Я хотел бы иметь какой-то дескриптор файла для файла, который выживает при перемещении/переименовании файла. Это не должно быть независимым от платформы, это нормально, если он работает только на Java7 + linux и даже отлично, если можно считать, что файлы не меняют каталог.Как найти файл, который был перемещен/переименован в Java

В данном случае я хочу записать источник входных данных журнала, похожий на входной файл logstash-file-input, то есть инструмент, который я могу запустить, чтобы зачеркнуть файл, и даже если этот файл будет повернут (т.е. перемещен/переименован), когда мое приложение для хвоста не работает, я хочу найти этот файл, когда приложение хвоста снова запустится.

Я посмотрел на BasicFileAttributes.fileKey, но я не нашел никакого способа перейти от fileKey к объекту File/Path.

Кто-нибудь знает, можно ли это сделать?

С наилучшими пожеланиями /Thomas

+0

Я не эксперт по Linux, но, возможно, вы могли бы создать жесткую ссылку на файл журнала в файловой системе и хвосте вместо фактического файла? – Philipp

+0

Возможно, вы используете ['WatchService'] (http://docs.oracle.com/javase/8/docs/api/java/nio/file/WatchService.html) для этого – fge

+0

@Philipp. да, это может быть способ, я видел ответ на подобные вопросы. Это кажется немного громоздким, хотя, возможно, наравне с написанием некоторого модуля JNI для этого. –

ответ

1

Это тривиальный демо, настраивая WatchService и ждать событий:

Path dir = Paths.get("/home", "me", "experiments"); 
WatchService watcher = dir.getFileSystem().newWatchService(); 
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); 
WatchKey key = watcher.take(); 
for (WatchEvent<?> event: key.pollEvents()) { 
    System.out.println(event.kind().name() + " " + event.context()); 
} 

Если mv xyz.dat abc.dat выполняется в ./experiments в то время как эта программа ждет в take() вызов, создается WatchKey, содержащий эти события:

ENTRY_DELETE zyx.dat 
ENTRY_CREATE xyz.dat 

c c ontext - относительный путь из каталога в измененный элемент.

Позже Можно зарегистрировать «идентификатор» файла в Linux, указав его устройство и индекс, возможно, добавив размер и дату создания. Затем, после восстановления контроля, вы можете найти этот файл, если он будет тем же самым каталогом.

Path dir = Paths.get("/home", "wlaun", "Java_Experiments"); 
Path file = dir.resolve("a.log"); 
Object fileKey = Files.getAttribute(file, "fileKey"); 
Object creaTime = Files.getAttribute(file, "creationTime"); 
System.out.println(fileKey.toString() + creaTime.toString()); 

Я должен добавить, что 1.8.0_20, похоже, запутывает creationTime и lastAccessTime.

+1

Лучше захватить 'WatchService', используя' Path': 'dir.getFileSystem(). NewWatchService()'. – fge

+0

Ах, да - не гарантируется наличие правильной файловой системы. Спасибо, изменен. – laune

+0

Это работает только в том случае, если мое приложение хвоста работает, когда происходит переименование/перемещение, или я что-то упускаю? Я прошу об этом позже, если мое приложение Java не работает в то время, когда произошел поворот. –

Смежные вопросы