2012-04-27 10 views
6

Tôi cần phải phân tích cú pháp tệp CSV lớn trong thời gian thực, trong khi đó là sửa đổi (được nối thêm) theo một quy trình khác. Bởi lớn, tôi có nghĩa là ~ 20 GB vào thời điểm này, và từ từ phát triển. Ứng dụng này chỉ cần phát hiện và báo cáo một số dị thường trong luồng dữ liệu, mà nó chỉ cần lưu trữ thông tin trạng thái nhỏ (không gian O(1)).Phân tích cú pháp các tệp văn bản lớn, được sửa đổi khi đang bay

Tôi đã suy nghĩ về việc bỏ phiếu các thuộc tính của tệp (kích thước) sau mỗi vài giây, mở luồng chỉ đọc, tìm kiếm vị trí trước đó và tiếp tục phân tích nơi tôi dừng lại lần đầu tiên. Nhưng vì đây là tệp văn bản (CSV), tôi rõ ràng cần phải theo dõi các ký tự dòng mới khi tiếp tục bằng cách nào đó, để đảm bảo tôi luôn phân tích toàn bộ dòng.

Nếu tôi không nhầm, đây không phải là vấn đề cần thực hiện, nhưng tôi muốn biết nếu có một cách phổ biến/thư viện nào giải quyết được một số vấn đề này chưa?

Lưu ý: Tôi không cần trình phân tích cú pháp CSV. Tôi cần thông tin về thư viện giúp đơn giản hóa các dòng đọc từ một tệp đang được sửa đổi khi đang di chuyển.

+0

Có thể ngừng xử lý csv không? Nếu có, tôi đề nghị bạn chuyển nó sang RDBMS. – Oybek

+0

@Oybek: bạn có thể làm rõ điều đó một chút không? Quá trình đó là phụ thêm vào tập tin được liên tục chạy, và tôi cần phải phân tích các dòng dữ liệu bằng đường liên tục (với vài giây chậm trễ). – Groo

+0

Tôi cho rằng bạn không có quyền kiểm soát quá trình phát ra tệp? –

Trả lời

1

Có một vấn đề nhỏ ở đây:

  • Đọc và phân tích cú pháp CSV đòi hỏi một TextReader
  • vị không hoạt động (cũng) với TextReaders.

Suy nghĩ đầu tiên: Hãy mở nó. Nếu cả hai nhà sản xuất và phân tích hoạt động trong chế độ không độc quyền Nó phải có khả năng readline-đến-null, tạm dừng, ReadLine-đến-null, vv


nó nên là 7-bit ASCII , chỉ một số Hướng dẫn và số điện thoại

Điều đó giúp bạn có thể theo dõi tệp Vị trí (pos + = line.Length + 2). Hãy chắc chắn rằng bạn mở nó với . Sau đó, bạn có thể mở lại dưới dạng luồng nhị phân đơn thuần, Tìm kiếm vị trí cuối cùng và chỉ sau đó đính kèm StreamReader vào luồng đó.

+0

Bạn nói đúng, có lẽ tốt hơn nhiều so với việc tìm kiếm. – Groo

+0

Crap, tôi thậm chí không xem xét các ký tự nhiều byte cho đến khi bạn đề cập đến nó. Một mẹo tuyệt vời nữa, cảm ơn! – Groo

0

Tại sao bạn không chỉ xoay vòng một quy trình/chủ đề riêng biệt mỗi khi bạn bắt đầu phân tích cú pháp - theo cách đó, bạn di chuyển phần đồng thời (trực tiếp) ra khỏi nguồn dữ liệu và về phía bồn chứa dữ liệu - bây giờ bạn chỉ cần phải tìm ra cách để thu thập kết quả từ tất cả các chủ đề của bạn ...

này sẽ có nghĩa là làm một đọc lại toàn bộ hồ sơ cho mỗi chủ đề mà bạn quay lên, mặc dù ...

Bạn có thể chạy một chương trình khác trên hai phiên bản và nhận từ đó, tùy thuộc vào nguồn dữ liệu csv được định dạng tốt như thế nào: Liệu nó có sửa đổi các bản ghi đã được viết không? Hay nó chỉ thêm các bản ghi mới?Nếu vậy, bạn chỉ có thể tách ra những thứ mới (cuối cùng vị trí để vãng eof) vào một tập tin mới, và xử lý những lúc giải trí trong một thread nền:

  • bỏ phiếu đề nhớ kích thước tập tin cuối cùng
  • khi tập tin được lớn hơn: tìm từ vị trí cuối cùng để kết thúc, lưu vào tập tin tạm thời
  • sợi nền xử lý bất kỳ tập tin tạm thời vẫn còn, trong trật tự sáng tạo/sửa đổi
+1

Vâng, kích thước của dữ liệu được thêm vào mỗi giây là tương đối nhỏ so với kích thước tập tin toàn bộ, và đó là lý do tại sao tôi muốn tránh đọc nó mỗi lần (nó có thể dễ dàng là 50GB sau một tuần đo). Và vì dữ liệu chỉ được nối thêm và các tệp rất lớn, khác biệt là không thực tế. Tôi cũng không hiểu phần về luồng: vì đây là một hoạt động đĩa, đọc sẽ không được hưởng lợi từ nhiều chủ đề, nó chỉ có thể chạy IMO chậm hơn và bước mà tôi ghi một phần tệp vào đĩa và sau đó mở lại có vẻ dư thừa (nếu tôi sao chép nó, tôi cũng có thể phân tích nó). – Groo

2

tôi đã không kiểm tra nó, nhưng tôi nghĩ rằng bạn có thể sử dụng FileSystemWatcher để phát hiện khi nào một quy trình khác đã sửa đổi tệp của bạn. Trong sự kiện đã thay đổi, bạn sẽ có thể tìm kiếm vị trí bạn đã lưu trước đó và đọc nội dung bổ sung.