Tôi đang viết trình phân tích cú pháp SAX trong Java để phân tích cú pháp tệp XML wikipedia 2.5GB. Có cách nào để theo dõi tiến trình phân tích cú pháp trong Java không?Theo dõi tiến trình phân tích cú pháp SAX của Java
Trả lời
Sử dụng số javax.swing.ProgressMonitorInputStream.
Giả sử bạn biết bạn có bao nhiêu bài viết, bạn có thể giữ một bộ đếm trong bộ xử lý không? Ví dụ.
public void startElement (String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
if(qName.equals("article")){
counter++
}
...
}
(Tôi không biết liệu bạn đang phân tích "bài viết", nó chỉ là một ví dụ)
Nếu bạn không biết số lượng các bài viết trước, bạn sẽ cần phải đếm nó đầu tiên . Sau đó, bạn có thể in trạng thái nb tags read/total nb of tags
, giả sử mỗi thẻ 100 (counter % 100 == 0
).
Hoặc thậm chí có một luồng khác theo dõi tiến độ. Trong trường hợp này, bạn có thể muốn đồng bộ hóa quyền truy cập vào bộ đếm, nhưng không cần thiết vì nó không cần phải thực sự chính xác.
2 cent Mỹ
Tôi đã tìm ra điều đó, nhưng tôi đang tìm cách để làm điều đó mà không cần đếm các bài viết trước. Tôi nghĩ có thể có một cách để tìm ra vị trí của trình phân tích cú pháp trong tệp thay vì, tôi có thể dễ dàng nhận được kích thước tệp. – Danijel
Bạn có thể nhận được một ước tính của dòng/cột hiện tại trong tập tin của bạn bằng cách ghi đè các phương pháp setDocumentLocator
của org.xml.sax.helpers.DefaultHandler/BaseHandler
. Phương thức này được gọi với một đối tượng mà từ đó bạn có thể nhận được một xấp xỉ của dòng/cột hiện tại khi cần thiết.
Chỉnh sửa: Theo hiểu biết tốt nhất của tôi, không có cách nào tiêu chuẩn để có được vị trí tuyệt đối. Tuy nhiên, tôi chắc chắn một số triển khai SAX cung cấp loại thông tin này.
Đóng, nhưng sau đó tôi sẽ phải biết số dòng trong tệp, phải không? – Danijel
Thật vậy. Một ý tưởng khác có thể đã được chỉ ra bởi EJP bí ẩn. Bạn có thể ước tính tiến độ, bằng cách sử dụng tiến bộ trong luồng đầu vào. Tuy nhiên, đây cũng không phải là tiến bộ trong phân tích cú pháp, bởi vì tiềm năng đệm và lookaheads. –
Tôi muốn sử dụng vị trí luồng đầu vào. Làm cho lớp dòng tầm thường của bạn đại diện/kế thừa từ một "thực" và theo dõi các byte đọc. Như bạn nói, việc tổng số tệp được dễ dàng. Tôi sẽ không lo lắng về việc lưu vào bộ đệm, xem xét, vv - đối với các tệp lớn như thế này, đó là nguồn cấp dữ liệu cho gà. Mặt khác, tôi sẽ giới hạn vị trí thành "99%".
Nhờ đề xuất của EJP là ProgressMonitorInputStream
, cuối cùng tôi mở rộng FilterInputStream
để có thể sử dụng ChangeListener
để theo dõi vị trí đọc hiện tại theo byte.
Với điều này bạn có quyền kiểm soát tốt hơn, ví dụ để hiển thị nhiều thanh tiến trình để đọc song song các tệp xml lớn. Đó là chính xác những gì tôi đã làm.
Vì vậy, một phiên bản đơn giản của con suối có thể giám sát:
/**
* A class that monitors the read progress of an input stream.
*
* @author Hermia Yeung "Sheepy"
* @since 2012-04-05 18:42
*/
public class MonitoredInputStream extends FilterInputStream {
private volatile long mark = 0;
private volatile long lastTriggeredLocation = 0;
private volatile long location = 0;
private final int threshold;
private final List<ChangeListener> listeners = new ArrayList<>(4);
/**
* Creates a MonitoredInputStream over an underlying input stream.
* @param in Underlying input stream, should be non-null because of no public setter
* @param threshold Min. position change (in byte) to trigger change event.
*/
public MonitoredInputStream(InputStream in, int threshold) {
super(in);
this.threshold = threshold;
}
/**
* Creates a MonitoredInputStream over an underlying input stream.
* Default threshold is 16KB, small threshold may impact performance impact on larger streams.
* @param in Underlying input stream, should be non-null because of no public setter
*/
public MonitoredInputStream(InputStream in) {
super(in);
this.threshold = 1024*16;
}
public void addChangeListener(ChangeListener l) { if (!listeners.contains(l)) listeners.add(l); }
public void removeChangeListener(ChangeListener l) { listeners.remove(l); }
public long getProgress() { return location; }
protected void triggerChanged(final long location) {
if (threshold > 0 && Math.abs(location-lastTriggeredLocation) < threshold) return;
lastTriggeredLocation = location;
if (listeners.size() <= 0) return;
try {
final ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener l : listeners) l.stateChanged(evt);
} catch (ConcurrentModificationException e) {
triggerChanged(location); // List changed? Let's re-try.
}
}
@Override public int read() throws IOException {
final int i = super.read();
if (i != -1) triggerChanged(location++);
return i;
}
@Override public int read(byte[] b, int off, int len) throws IOException {
final int i = super.read(b, off, len);
if (i > 0) triggerChanged(location += i);
return i;
}
@Override public long skip(long n) throws IOException {
final long i = super.skip(n);
if (i > 0) triggerChanged(location += i);
return i;
}
@Override public void mark(int readlimit) {
super.mark(readlimit);
mark = location;
}
@Override public void reset() throws IOException {
super.reset();
if (location != mark) triggerChanged(location = mark);
}
}
Nó không biết - hoặc chăm sóc - lớn như thế nào dòng cơ bản là, vì vậy bạn cần phải nhận được nó một cách khác, chẳng hạn như từ chính tệp đó.
Vì vậy, ở đây đi việc sử dụng mẫu đơn giản:
try (
MonitoredInputStream mis = new MonitoredInputStream(new FileInputStream(file), 65536*4)
) {
// Setup max progress and listener to monitor read progress
progressBar.setMaxProgress((int) file.length()); // Swing thread or before display please
mis.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) {
SwingUtilities.invokeLater(new Runnable() { @Override public void run() {
progressBar.setProgress((int) mis.getProgress()); // Promise me you WILL use MVC instead of this anonymous class mess!
}});
}});
// Start parsing. Listener would call Swing event thread to do the update.
SAXParserFactory.newInstance().newSAXParser().parse(mis, this);
} catch (IOException | ParserConfigurationException | SAXException e) {
e.printStackTrace();
} finally {
progressBar.setVisible(false); // Again please call this in swing event thread
}
Trong trường hợp của tôi tiến bộ nâng cao độc đáo từ trái sang phải mà không nhảy bất thường. Điều chỉnh ngưỡng để cân bằng tối ưu giữa hiệu suất và khả năng phản hồi. Quá nhỏ và tốc độ đọc có thể nhiều hơn sau đó tăng gấp đôi trên các thiết bị nhỏ, quá lớn và tiến trình sẽ không được mịn màng.
Hy vọng điều đó sẽ hữu ích. Vui lòng chỉnh sửa nếu bạn tìm thấy lỗi hoặc lỗi chính tả hoặc bỏ phiếu để gửi cho tôi một số khuyến khích!: D
Tuyệt vời! Chính xác những gì tôi đang tìm kiếm, tôi sẽ thích ứng với điều đó, cảm ơn! :) – Matthieu
- 1. Phân tích html với trình phân tích cú pháp SAX
- 2. Sự khác biệt giữa trình phân tích cú pháp SAX XML, Kéo trình phân tích cú pháp & Trình phân tích cú pháp DOM trong android
- 3. XML phân tích cú pháp - ElementTree vs SAX và DOM
- 4. Trình phân tích cú pháp SAX java có thực sự truy xuất DTD từ Internet không?
- 5. Trình phân tích cú pháp email Java?
- 6. Phân tích cú pháp XML với SAX trong java, phân biệt chữ hoa chữ thường.
- 7. Kết hợp phân tích cú pháp phân tích cú pháp, phân tích cú pháp và phân tích cú pháp rừng
- 8. Vị trí theo dõi khi quét các thẻ làm phức tạp trình phân tích cú pháp
- 9. Chọn trình phân tích cú pháp Haskell
- 10. Trình tạo trình phân tích cú pháp và trình phân tích cú pháp cho Common Lisp
- 11. Trình theo dõi tiến trình theo dõi lưu lượng video?
- 12. Trình phân tích cú pháp địa chỉ bưu điện Java
- 13. Trình phân tích cú pháp Java được viết bằng JavaScript
- 14. Trình theo dõi phân tích google của Google NoClassdefFoundError
- 15. Trình phân tích cú pháp SVG Python
- 16. Phân tích cú pháp chung của PB trong java
- 17. Trình phân tích cú pháp phân tích cú pháp của scala có phân tích cú pháp các tệp nhị phân không?
- 18. Cách xóa #text khỏi phân tích cú pháp Nút của tôi trong phân tích cú pháp xml của Java dom
- 19. Cần trình phân tích cú pháp C++
- 20. trình phân tích cú pháp node.js xml trên windows
- 21. Trình phân tích cú pháp SAX của Android không nhận được toàn văn từ giữa các thẻ
- 22. Làm cách nào để trả về dữ liệu từ trình phân tích cú pháp SAX của Python?
- 23. Trình phân tích cú pháp HTML
- 24. Trình phân tích cú pháp Wiki nào?
- 25. Trình phân tích cú pháp phân tích cú pháp Haskell để gặp phải [...]
- 26. Phân tích cú pháp XML Libxmljs (Node.js)
- 27. Thiết lập mã hóa cho phân tích cú pháp sax bằng Python
- 28. Phân tích cú pháp XML của Python
- 29. Phân tích cú pháp __utmz cookie theo dõi để nhận giới thiệu
- 30. Chọn đúng trình phân tích cú pháp XML của IBM
Tôi nghĩ điều này sẽ đủ gần. Cảm ơn! – Danijel
Câu trả lời có thể đơn giản hơn thế không ?! :) – Matthieu