2010-03-29 23 views
9

Tôi cần để có thể bắt chước 'tail -f' với Java. Tôi đang cố gắng đọc một tệp nhật ký vì nó đang được viết bởi một tiến trình khác, nhưng khi tôi mở tệp để đọc nó, nó khóa tệp và quá trình khác không thể ghi vào nó nữa. Mọi sự trợ giúp sẽ rất được trân trọng!Java: mở và đọc từ một tệp mà không khóa nó

Đây là mã mà tôi hiện đang sử dụng:

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

Nếu không có công trình nào khác hoạt động, bạn có thể sử dụng jni để truy cập vào win32 api (giả sử bạn đang sử dụng windows, nếu không bạn đang làm việc với api nào). – Blindy

+1

sử dụng win32 api sẽ là điều xấu nhất;) – Bozho

+0

Heh vì tôi không biết Java tốt, đó là lời khuyên tốt nhất tôi có :) – Blindy

Trả lời

0

Nhìn vào API FileChannel here. Để khóa tệp, bạn có thể kiểm tra here

+0

Bạn có thể xem câu hỏi trùng lặp có thể có trong stackoverflow tại http://stackoverflow.com/questions/128038/how-can-i-lock-a-file- sử dụng-java-nếu-có thể – Cshah

+0

Hmm. Tôi đã xem xét nó và thử một số chiến lược - thậm chí sử dụng java.io.RandomAccessFile ngoài FileChannel, nhưng tôi vẫn không thể quản lý để cho một quá trình ghi vào một tập tin mà tôi đang đọc trong Java. – rogue780

+0

rogue780 - đăng các chiến lược bạn đã thử. Lưu ý rằng nếu quá trình khác đòi hỏi một khóa độc quyền trước khi nó ghi vào tập tin, sau đó bạn đang khá nhiều bánh mì nướng (tất nhiên, đuôi sẽ không làm việc trong tình huống này). Nhưng bạn đã thử khóa (với một khóa đọc không độc quyền) phần trên cùng của tập tin? –

0

Windows sử dụng khóa bắt buộc cho tệp trừ khi bạn chỉ định cờ chia sẻ phù hợp khi mở. Nếu bạn muốn mở một tập tin bận, bạn cần phải sử dụng Win32-API CreateFile một tay cầm với các cờ chia sẻ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE.

Điều này được sử dụng bên trong JDK ở một vài nơi để mở tệp để đọc thuộc tính và nội dung, nhưng theo tôi có thể thấy nó không được xuất/có sẵn cho cấp thư viện lớp Java. Vì vậy, bạn sẽ cần phải tìm một thư viện bản địa để làm điều đó.

Tôi nghĩ như một tác phẩm nhanh chóng xung quanh bạn có thể đọc process.getInputStream() từ lệnh "cmd /D/C type file.lck"

+1

Tôi không chắc chắn khi nào thay đổi, nhưng tệp của tôi được mở bằng RandomAccessFile sẽ mở ra với SHARE_READ và SHARE_WRITE. Tôi đã thử nghiệm bằng cách sử dụng ProcMon.exe – kervin

0

Nếu bạn muốn có một giải pháp nhanh chóng, mà có thể không phải là thanh lịch nhất, chỉ đơn giản là theo dõi các tập tin thay đổi kích thước, sau đó mở tập tin , tìm đến vị trí cuối cùng, đọc dữ liệu mới, đóng tệp và theo dõi.

Và nếu hiệu suất không phải là mối quan tâm, điều này sẽ chỉ hoạt động tốt. Tuy nhiên, nếu bạn cần hiệu suất, một số giải pháp phức tạp hơn dựa trên một số API IO tập tin nâng cao hơn nên được ưu tiên.

+0

Không nếu anh ta không thể mở nó do khóa. – EJP

5

Đắp lại đuôi là khó khăn do một số trường hợp đặc biệt như cắt tệp và xóa (trung gian). Để mở tập tin mà không cần khóa sử dụng StandardOpenOption.READ với các API tập tin Java mới như vậy:

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. 
    } 
} 

Đối với nỗ lực của tôi để tạo một cái đuôi trong Java xem:

Hãy lấy cảm hứng từ mã đó hoặc chỉ cần sao chép các phần bạn yêu cầu. Hãy cho tôi biết nếu bạn tìm thấy bất kỳ vấn đề nào mà tôi không biết.

Các vấn đề liên quan