2010-03-29 4 views
9

Мне нужно уметь имитировать 'tail -f' с Java. Я пытаюсь прочитать файл журнала, поскольку он написан другим процессом, но когда я открываю файл для его чтения, он блокирует файл, а другой процесс больше не может писать. Любая помощь будет принята с благодарностью!Java: открытие и чтение из файла без его блокировки

Вот код, который я использую в настоящее время:

public void read(){ 
    Scanner fp = null; 
    try{ 
     fp = new Scanner(new FileReader(this.filename)); 
     fp.useDelimiter("\n"); 
    }catch(java.io.FileNotFoundException e){ 
     System.out.println("java.io.FileNotFoundException e"); 
    } 
    while(true){ 
     if(fp.hasNext()){ 
      this.parse(fp.next()); 
     }   
    }  
} 
+0

Если ничего не работает, вы можете использовать jni, чтобы перейти к win32 api (при условии, что вы находитесь на окнах, иначе все, с чем вы работаете). – Blindy

+1

с помощью win32 api было бы самым уродливым;) – Bozho

+0

Хех, так как я не знаю Java, это хорошо, это лучший совет, который у меня есть :) – Blindy

ответ

0

Посмотрите на FileChannel API here. Для блокировки файла вы можете проверить here

+0

Вы можете посмотреть на возможный дублирующий вопрос в stackoverflow по адресу http://stackoverflow.com/questions/128038/how-can-i-lock-a-file- использование-java-если возможно – Cshah

+0

Hmm. Я просмотрел его и попробовал несколько стратегий - даже используя java.io.RandomAccessFile в дополнение к FileChannel, но я все еще не могу позволить другому процессу записывать в файл, который я читаю на Java. – rogue780

+0

rogue780 - опубликуйте стратегии, которые вы пробовали. Обратите внимание, что если другой процесс требует эксклюзивной блокировки перед записью в файл, то вы довольно много тостов (конечно, хвост тоже не будет работать в этой ситуации). Но попытались ли вы заблокировать (с неэксклюзивной блокировкой чтения) верхнюю часть файла? –

0

Windows использует обязательную блокировку файлов, если вы не укажете правильные флаги общего доступа во время открытия. Если вы хотите открыть загруженный файл, вам понадобится Win32-API CreateFile ручка с флагами обмена FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE.

Это используется внутри JDK в нескольких местах, чтобы открывать файлы для чтения атрибутов и т. Д., Но насколько я вижу, он не экспортируется и не доступен для уровня библиотеки классов Java. Таким образом, вам нужно будет найти собственную библиотеку.

Я думаю, что в качестве быстрой работы вокруг вас может прочитать process.getInputStream() из команды "cmd /D/C type file.lck"

+1

Я не уверен, когда он изменился, но мой файл, открытый с использованием RandomAccessFile, открывается с помощью SHARE_READ и SHARE_WRITE. Я тестировал с помощью ProcMon.exe – kervin

0

Если вы хотите быстрое решение, которое не может быть самый элегантный, просто контролировать файл для изменения размера, а затем открыть файл , найдите последнюю позицию, прочитайте новые данные, закройте файл и продолжайте мониторинг.

И если производительность не вызывает беспокойства, это должно работать нормально. Если, однако, вам нужна производительность, предпочтительнее другое более сложное решение, основанное на более продвинутом IO API файлов.

+0

Не, если он не может открыть его из-за блокировки. – EJP

5

Восстановление хвоста сложно из-за некоторых особых случаев, таких как усечение файлов и (промежуточное) удаление. Чтобы открыть файл без блокировки использования StandardOpenOption.READ с новым файлом Java API, как так:

try (InputStream is = Files.newInputStream(path, StandardOpenOption.READ)) { 
    InputStreamReader reader = new InputStreamReader(is, fileEncoding); 
    BufferedReader lineReader = new BufferedReader(reader); 
    // Process all lines. 
    String line; 
    while ((line = lineReader.readLine()) != null) { 
     // Line content content is in variable line. 
    } 
} 

Для моей попытки создать хвост в Java см:

Не стесняйтесь вникать в этот код или просто скопировать нужные детали. Дайте мне знать, если вы найдете какие-либо проблемы, о которых я не знаю.