Tôi muốn được thông báo khi một tệp đã được thay đổi trong hệ thống tệp. Tôi đã tìm thấy gì, nhưng một chủ đề mà thăm dò tài sản LastModified File và rõ ràng giải pháp này không phải là tối ưu.Người nghe đã thay đổi tệp trong Java
Trả lời
Ở cấp độ thấp, cách duy nhất để lập mô hình tiện ích này là có một cuộc thăm dò chuỗi trên một thư mục và giữ một chiếc đồng hồ trên các thuộc tính của tệp. Nhưng bạn có thể sử dụng các mẫu để phát triển một bộ điều hợp cho một tiện ích như vậy.
Ví dụ: máy chủ ứng dụng j2ee như Tomcat và các máy chủ khác có tính năng tải tự động trong đó ngay sau khi thay đổi bộ mô tả triển khai hoặc lớp servlet thay đổi ứng dụng khởi động lại.
Bạn có thể sử dụng các thư viện từ các máy chủ như hầu hết mã của tomcat đều có thể sử dụng lại và được mở.
Điều này không còn đúng trong Java 7: bây giờ có một API cho điều này có thể móc vào các dịch vụ thông báo của hệ điều hành: http://blogs.oracle.com/thejavatutorials/entry/watching_a_directory_for_changes –
API đó là không đủ, nó không cung cấp thông báo cho các sự kiện đóng tệp trên Linux. Vì vậy, cho một trường hợp đơn giản, khi một tập tin được đóng lại, sao chép nó vào một thư mục khác không hoạt động. –
Nếu bạn sẵn sàng tham gia một số tiền, JNIWrapper là thư viện hữu ích với Winpack, bạn sẽ có thể nhận các sự kiện hệ thống tệp trên một số tệp nhất định. Thật không may chỉ có cửa sổ.
http://www.teamdev.com/jniwrapper/index.jsf
Nếu không, phải dùng đến mã nguồn gốc không phải lúc nào cũng là một điều xấu nhất là khi sản phẩm tốt nhất trên cung cấp là một cơ chế bỏ phiếu như chống lại một sự kiện tự nhiên .
Tôi đã nhận thấy rằng hoạt động của hệ thống tệp java có thể chậm trên một số máy tính và có thể dễ dàng ảnh hưởng đến hiệu suất của ứng dụng nếu không được xử lý tốt.
Có một lib được gọi là jnotify kết thúc tốt đẹp inotify trên Linux và cũng hỗ trợ cửa sổ. Không bao giờ sử dụng nó và tôi không biết nó tốt như thế nào, nhưng nó có giá trị một thử tôi muốn nói.
Nó hoạt động hoàn hảo và siêu đơn giản để sử dụng. Tôi đã sử dụng inotify trong nhiều năm. Đó là nhanh chóng, ổn định và đáng tin cậy –
Tôi đã viết một tệp nhật ký theo dõi trước đây và tôi thấy rằng tác động đến hiệu suất hệ thống của việc bỏ phiếu các thuộc tính của một tệp, một vài lần một giây, thực sự rất nhỏ.
Java 7, như một phần của NIO.2 đã bổ sung API WatchService API
Các WatchService được thiết kế cho các ứng dụng cần phải được thông báo về các sự kiện thay đổi tập tin.
tôi thấy các ví dụ như xem thư mục, nhưng những gì về một tập tin cá nhân? –
@ArchimedesTrajano API thông báo cho bạn khi một tệp trong thư mục đã thay đổi. Sự kiện được kích hoạt bao gồm tên của tệp đã thay đổi. Vì vậy, bạn có thể xử lý các sự kiện cho một tệp hoặc tệp nhất định và bỏ qua những người khác. – Michael
@ArchimedesTrajano https://stackoverflow.com/questions/16251273/can-i-watch-for-single-file-change-with-watchservice-not-the-whole-directory – user1742529
"Nhiều tính năng NIO" có chức năng xem tệp, với việc triển khai phụ thuộc vào hệ điều hành cơ bản. Nên có trong JDK7.
Bạn có thể cụ thể hơn hoặc đăng liên kết không để tài liệu? Có vẻ như không tìm thấy bất cứ điều gì về điều này ... – Luciano
tôi sử dụng API VFS từ Apache Commons, đây là một ví dụ về làm thế nào để theo dõi một tập tin mà không ảnh hưởng nhiều trong hoạt động:
cảm ơn câu trả lời này!chính xác những gì tôi đã tìm kiếm… –
rất hữu ích, cảm ơn –
Có một thư viện chéo máy tính để bàn thương mại cho các tập tin và thư mục xem được gọi là JxFileWatcher. Nó có thể được tải về từ đây: http://www.teamdev.com/jxfilewatcher/
Ngoài ra bạn có thể nhìn thấy nó trong hành động trực tuyến: http://www.teamdev.com/jxfilewatcher/onlinedemo/
Bạn cũng có thể xem xét Apache Commons JCI (Java Compiler Interface). Mặc dù API này dường như tập trung vào việc biên dịch động các lớp, nhưng nó cũng bao gồm các lớp trong API của nó để theo dõi các thay đổi của tệp.
Xuân Tích hợp cung cấp một cơ chế tốt đẹp cho xem Thư mục và tập tin: http://static.springsource.org/spring-integration/reference/htmlsingle/#files. Khá chắc chắn đó là nền tảng chéo (tôi đã sử dụng nó trên mac, linux, và cửa sổ).
Tôi chạy đoạn mã này mỗi khi tôi đọc tệp thuộc tính, chỉ thực sự đọc tệp nếu tệp đã được sửa đổi kể từ lần cuối tôi đọc nó. Hy vọng điều này sẽ giúp một ai đó.
private long timeStamp;
private File file;
private boolean isFileUpdated(File file) {
this.file = file;
this.timeStamp = file.lastModified();
if(this.timeStamp != timeStamp) {
this.timeStamp = timeStamp;
//Yes, file is updated
return true;
}
//No, file is not updated
return false;
}
Cách tiếp cận tương tự được sử dụng trong Log4J FileWatchdog
.
Java commons-io có FileAlterationObserver. nó sẽ bỏ phiếu kết hợp với một FileAlterationMonitor. Tương tự như VFS. Ưu điểm là nó có ít phụ thuộc hơn nhiều.
chỉnh sửa: Ít phụ thuộc không đúng, chúng là tùy chọn cho VFS. Nhưng nó sử dụng java File thay vì lớp trừu tượng VFS.
Bạn có thể nghe các thay đổi tệp bằng cách sử dụng Trình đọc tài liệu. Plz xem ví dụ dưới đây
// File content change listener
private String fname;
private Object lck = new Object();
...
public void run()
{
try
{
BufferedReader br = new BufferedReader(new FileReader(fname));
String s;
StringBuilder buf = new StringBuilder();
while(true)
{
s = br.readLine();
if(s == null)
{
synchronized(lck)
{
lck.wait(500);
}
}
else
{
System.out.println("s = " + s);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
Polling thuộc tính tập tin sửa đổi lần cuối là một giải pháp đơn giản nhưng hiệu quả mặc dù. Chỉ cần xác định một lớp mở rộng FileChangedWatcher
của tôi và thực hiện các onModified()
phương pháp:
import java.io.File;
public abstract class FileChangedWatcher
{
private File file;
public FileChangedWatcher(String filePath)
{
file = new File(filePath);
}
public void watch() throws InterruptedException
{
long currentModifiedDate = file.lastModified();
while (true)
{
long newModifiedDate = file.lastModified();
if (newModifiedDate != currentModifiedDate)
{
currentModifiedDate = newModifiedDate;
onModified();
}
Thread.sleep(100);
}
}
public String getFilePath()
{
return file.getAbsolutePath();
}
protected abstract void onModified();
}
Tương tự như các câu trả lời khác, dưới đây là cách tôi đã làm nó sử dụng File, Timer, và TimerTask để cho hoạt động này như một điểm bỏ phiếu sợi nền trong khoảng thời gian thiết lập .
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
public class FileModifiedWatcher
{
private static File file;
private static int pollingInterval;
private static Timer fileWatcher;
private static long lastReadTimeStamp = 0L;
public static boolean init(String _file, int _pollingInterval)
{
file = new File(_file);
pollingInterval = _pollingInterval; // In seconds
watchFile();
return true;
}
private static void watchFile()
{
if (null == fileWatcher)
{
System.out.println("START");
fileWatcher = new Timer();
fileWatcher.scheduleAtFixedRate(new TimerTask()
{
@Override
public void run()
{
if (file.lastModified() > lastReadTimeStamp)
{
System.out.println("File Modified");
}
lastReadTimeStamp = System.currentTimeMillis();
}
}, 0, 1000 * pollingInterval);
}
}
}
- 1. Java - Nghe thay đổi biến
- 2. viết một người nghe thay đổi tập tin trong ruby
- 3. thêm người nghe vs người nghe đã đặt
- 4. Thêm một người nghe vào một biến trong Java/JavaFX được gọi là thay đổi biến
- 5. Người nghe sự kiện trong Java
- 6. Sự kiện đã thay đổi hướng sự kiện hoặc người nghe Android
- 7. Bắn người nghe JPA về thay đổi trường sưu tập
- 8. Quá nhiều tệp đang mở (ulimit đã thay đổi)
- 9. jQuery: Cách nghe các thay đổi DOM?
- 10. ContentObserver để thay đổi liên hệ nghe
- 11. Xem tất cả các tệp đã thay đổi trong TFS
- 12. Tìm các tệp đã thay đổi trong thư mục ClearCase
- 13. onNewIntent() vòng đời và người nghe đã đăng ký
- 14. Trình nghe thư mục trong Java
- 15. Đặt tất cả các tệp đã thay đổi vào danh sách thay đổi trong SVN
- 16. gitolite: chỉ cho phép thay đổi các tệp đã chọn
- 17. Trình nghe thay đổi thuộc tính CSS
- 18. InnoSetup: không gỡ cài đặt các tệp đã thay đổi
- 19. Tạo trình nghe tùy chỉnh Trong Java
- 20. Bản sao CMake nếu tệp gốc đã thay đổi
- 21. Người nghe nào có thể biết rằng giá trị JTextPane bị thay đổi?
- 22. Nghe trên ButtonGroup cho các thay đổi "con", và in văn bản đã chọn của JRadioButton
- 23. Trình nghe tín hiệu - chỉ thực hiện hành động nếu một trường đã thay đổi
- 24. Nghe để thay đổi lớp học trong jquery
- 25. Nhận ANT chỉ quét các tệp mới/đã thay đổi
- 26. Trình nghe thay đổi giá trị tế bào JTable
- 27. Phông chữ Indigo Eclipse đã thay đổi
- 28. Không có gì thay đổi, nhưng eclipse egit đánh dấu tệp là đã thay đổi
- 29. Egit hiển thị tất cả các tệp đã thay đổi
- 30. Django: Chỉ thu thập các tệp tĩnh đã thay đổi
Cảm ơn tất cả các câu trả lời. Vì nhu cầu của tôi là nhỏ (tôi chỉ cần tải lại một tệp tin thuộc tính đã thay đổi trong ứng dụng web của tôi .. chính vì việc khởi động lại toàn bộ webapp là chậm), tôi sẽ giữ nguyên mô hình thăm dò ý kiến. Ít nhất bây giờ tôi biết rằng không có một giải pháp đơn giản cho các trường hợp đề tài. – cheng81
Chỉ cần lưu ý. Khi chúng tôi giải quyết vấn đề này trước khi chúng tôi thấy rằng các tệp lớn có xu hướng chậm, và cơ chế bỏ phiếu thường phát hiện một tệp mới hoặc đã thay đổi trước khi tệp được viết hoàn toàn. Để giải quyết điều này, một giải pháp 'cắn hai' đã được áp dụng. Các poller nhận thấy một tập tin đã thay đổi, nhưng không thông báo cho hệ thống của một tập tin mới/thay đổi cho đến khi nó trông giống nhau cho hai cuộc thăm dò: tức là đã ổn định. Chữa khỏi rất nhiều lỗi badfile. –
Là một sang một bên, Tomcat bị vấn đề đó khi thả các tệp WAR lớn vào thư mục webapps từ các nguồn từ xa và đã làm như vậy trong một thời gian dài. –