2009-04-23 51 views
7

Tôi quan tâm đến việc phân tích cú pháp một tệp văn bản khá lớn trong Java (1.6.x) và tự hỏi xem phương pháp nào được coi là phương pháp hay nhất?Phân tích cú pháp các tệp văn bản lớn trong thời gian thực (Java)

Tệp có thể có kích thước khoảng 1Mb và sẽ bao gồm hàng nghìn mục nhập dọc theo các dòng;

Entry 
{ 
    property1=value1 
    property2=value2 
    ... 
} 

, vv

bản năng đầu tiên của tôi là sử dụng biểu thức thông thường, nhưng tôi không có kinh nghiệm trước đây của việc sử dụng Java trong một môi trường sản xuất, và do đó không chắc chắn cách mạnh mẽ các lớp java.util.regex là .

Để làm rõ một chút, ứng dụng của tôi sẽ trở thành ứng dụng web (JSP) phân tích tệp được đề cập và hiển thị các giá trị khác nhau mà tệp truy xuất. Chỉ có một tệp được phân tích cú pháp (nó nằm trong thư mục của bên thứ ba trên máy chủ).

Ứng dụng sẽ có mức sử dụng khá thấp (có thể chỉ một số ít người dùng sử dụng nó vài lần trong ngày), nhưng điều quan trọng là khi họ sử dụng, thông tin sẽ được truy xuất nhanh nhất có thể.

Ngoài ra, có bất kỳ biện pháp phòng ngừa nào để thực hiện việc tải tệp vào bộ nhớ mỗi khi được phân tích cú pháp không?

Có ai có thể đề xuất phương pháp tiếp cận ở đây không?

Cảm ơn

+2

Bạn có nghĩa là thời gian thực hoặc nhanh chóng không? Hai là rất khác nhau. Thời gian thực ngụ ý rằng bạn đưa ra câu trả lời cho mọi đầu vào mà không phải đợi thêm đầu vào. Điều này thường chậm hơn so với xử lý theo lô. –

+3

Ngoài ra, 1 meg không còn được coi là lớn trừ khi bạn đang chạy trên một máy có bộ nhớ ít hơn 64 meg. –

+0

Ý tôi là - Tôi muốn yêu cầu được gửi từ giao diện người dùng web đến máy chủ, sẽ báo hiệu rằng nó sẽ phân tích cú pháp tệp và trả về kết quả (vào bất kỳ cấu trúc dữ liệu nào thích hợp) và sau đó xử lý chúng để hiển thị giao diện người dùng. –

Trả lời

8

Nếu định dạng khoảng 1MB và theo nghĩa đen, bạn có vẻ như đang làm quá nhiều thứ. Trừ khi máy chủ của bạn là một ZX Spectrum hoặc một cái gì đó, chỉ cần sử dụng biểu thức thông thường để phân tích nó, whack dữ liệu trong một bản đồ băm (và giữ nó ở đó), và đừng lo lắng về nó. Nó sẽ chiếm một vài megabyte trong bộ nhớ, nhưng vì vậy những gì ...?

Cập nhật: chỉ để cung cấp cho bạn một ý tưởng cụ thể về hiệu suất, một số đo tôi mất của performance of String.split() (trong đó sử dụng biểu thức thông thường) cho thấy trên một máy 2GHz, phải mất mili giây để chia 10.000 chuỗi 100 ký tự (nói cách khác, khoảng 1 megabyte dữ liệu - thực sự gần 2MB với khối lượng thuần túy của byte, vì Strings là 2 byte trên mỗi char). Obvioualy, đó không phải là hoạt động bạn đang thực hiện, nhưng bạn nhận được quan điểm của tôi: những thứ không phải là xấu ...

+0

Đủ công bằng - đó thực sự là điều mà tôi cũng đang thắc mắc - nếu tôi có vấn đề này trong đầu của tôi. Tôi nghĩ tôi sẽ làm như bạn nói và xem cách tôi tiếp tục. Nếu hiệu suất trở thành một vấn đề thì tôi có thể quay lại và xem xét các tùy chọn được đề xuất bởi các câu trả lời khác. Chúc mừng. –

+1

Tôi thành thật không nghĩ rằng nó sẽ được - 1MB thực sự không phải là rất nhiều dữ liệu. –

5

Nếu nó là một ngữ pháp thích hợp, sử dụng một người thợ xây phân tích cú pháp như GOLD Parsing System. Điều này cho phép bạn chỉ định định dạng và sử dụng một trình phân tích cú pháp hiệu quả để nhận các mã thông báo bạn cần, xử lý lỗi gần như miễn phí.

4

Tôi tự hỏi tại sao điều này không có trong XML và sau đó bạn có thể tận dụng công cụ XML có sẵn. Tôi đang suy nghĩ đặc biệt của SAX, trong trường hợp này bạn có thể dễ dàng phân tích/xử lý điều này mà không cần giữ tất cả trong bộ nhớ.

Vì vậy, bạn có thể chuyển đổi điều này thành XML không?

If you can not, và bạn cần một phân tích cú pháp, sau đó hãy nhìn vào JavaCC

+0

Đó là tệp nhật ký của bên thứ 3, tôi không kiểm soát được định dạng này. –

3

Sử dụng lớp Scanner và xử lý tập tin của bạn một dòng tại một thời điểm. Im không chắc chắn lý do tại sao bạn đề cập đến regex. Regex gần như không bao giờ là câu trả lời đúng cho bất kỳ câu hỏi phân tích cú pháp nào vì sự mơ hồ và thiếu sự tranh cãi về những gì xảy ra trong bối cảnh nào.

+0

Vui lòng cho chúng tôi biết các cụm từ thông dụng không rõ ràng. Có, các hương vị khác nhau hoạt động khác nhau, nhưng tất cả chúng đều được ghi chép và nhất quán (nhiều hay ít). Mỗi biểu thức, cho một hương vị nhất định, có một ý nghĩa chính xác và rõ ràng. –

+0

Khi họ (RegEx) trở nên phức tạp, họ không làm những gì mọi người tin rằng họ đang thực sự làm. Các vấn đề phân tích cú pháp thực và giải pháp của họ không bao giờ sử dụng RegExs. Có bất kỳ trình biên dịch bằng văn bản với RegExs? –

+1

@ mP.Khi mọi người không có xu hướng hiểu điều gì đó rõ ràng, họ thường gọi nó là "THE AMBIGUOUS" ;; Chỉ cần dành một chút thời gian để hiểu nó, Điều này làm giảm nỗ lực rất nhiều ... – KDjava

2

Bạn có thể sử dụng trình tạo phân tích cú pháp Antlr để tạo trình phân tích cú pháp có khả năng phân tích cú pháp tệp của bạn.

1

Không trả lời câu hỏi về phân tích cú pháp ... nhưng bạn có thể phân tích cú pháp các tệp và tạo các trang tĩnh ngay sau khi các tệp mới đến. Vì vậy, bạn sẽ không có vấn đề hiệu suất ... (Và tôi nghĩ 1Mb không phải là một tệp lớn để bạn có thể tải nó trong bộ nhớ, miễn là bạn không tải quá nhiều tệp cùng lúc ...)

+0

Đó là cùng một tệp đang được phân tích cú pháp mọi lúc - chỉnh sửa bài đăng để làm rõ điều đó. –

1

có vẻ như một định dạng tệp đủ đơn giản, vì vậy bạn có thể xem xét sử dụng một số Recursive Descent Parser. So với JavaCC và Antlr, những ưu điểm của nó là bạn có thể viết một vài phương thức đơn giản, lấy dữ liệu bạn cần, và bạn không cần phải tìm hiểu một hình thức trình tạo trình phân tích cú pháp. Khuyết điểm của nó - nó có thể kém hiệu quả hơn. Trình phân tích cú pháp gốc đệ quy về nguyên tắc mạnh hơn các biểu thức thông thường. Nếu bạn có thể đưa ra một ngữ pháp cho loại tập tin này, nó sẽ phục vụ bạn cho bất cứ giải pháp nào bạn chọn.

1

Nếu đó là những hạn chế của các regex Java bạn đang thắc mắc, đừng lo lắng về nó . Giả sử bạn có khả năng hợp lý trong việc tạo các regex, hiệu suất không phải là một vấn đề. Bộ tính năng cũng rất phong phú - bao gồm cả yêu thích của tôi, possessive quantifiers.

1

giải pháp khác là thực hiện một số hình thức tiền xử lý (được thực hiện ngoại tuyến, hoặc dưới dạng cron job) tạo ra cấu trúc dữ liệu được tối ưu hóa, sau đó được sử dụng để phục vụ nhiều yêu cầu web (không cần phải sao chép tệp) .

mặc dù, nhìn vào kịch bản được đề cập, dường như không cần thiết.

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