2011-02-01 44 views
10

Tôi phải đọc một tệp văn bản lớn (> 10 GB) trong C++. Đây là tệp csv có các dòng độ dài thay đổi. khi tôi cố gắng đọc từng dòng bằng cách sử dụng ifstream nó hoạt động nhưng mất thời gian dài, tôi đoán điều này là bởi vì mỗi lần tôi đọc một dòng nó đi vào đĩa và đọc, mà làm cho nó rất chậm. Có một cách để đọc trong bộ đệm, ví dụ đọc 250 MB tại một shot (sử dụng phương pháp đọc của ifstream) và sau đó nhận được dòng từ bộ đệm này, tôi thấy rất nhiều vấn đề với giải pháp như bộ đệm có thể có dòng không đầy đủ, v.v. ..Đọc txt lớn hiệu quả trong C++

Có một giải pháp cho điều này trong C++ mà xử lý tất cả các trường hợp này vv Có bất kỳ thư viện nguồn mở nào có thể làm điều này ví dụ như tăng vv không?

Lưu ý: Tôi muốn tránh c stye FILE * con trỏ, v.v.

+1

Thư viện chuẩn đã sử dụng bộ đệm. Phải mất một thời gian dài vì tệp lớn. Có thể bạn đang làm gì đó khác. Đăng mã bạn sử dụng, chúng tôi có thể bình luận về điều đó. –

Trả lời

7

Thử sử dụng chức năng tệp ánh xạ bộ nhớ Windows. Các cuộc gọi được đệm và bạn nhận được để điều trị một tập tin như thể bộ nhớ chỉ của nó. memory mapped files

+0

unix luôn có mmap() cho điều này ... – vrdhn

+0

Trừ khi môi trường là 64b, sẽ không thể ánh xạ toàn bộ tệp 10 GB vào một chế độ xem, do đó ngay cả với ranh giới đường tiếp cận này cũng cần được xử lý giống như bộ đệm . Điều đó nói rằng, dựa vào hệ điều hành để xử lý tất cả các I/O và đệm bằng cách sử dụng các tập tin bộ nhớ ánh xạ vẫn còn thú vị và mang lại hiệu suất tuyệt vời. – Suma

3

IOstream đã sử dụng bộ đệm nhiều như bạn mô tả (mặc dù thường chỉ có vài kilobyte, không phải hàng trăm megabyte). Bạn có thể sử dụng pubsetbuf để có được nó để sử dụng một bộ đệm lớn hơn, nhưng tôi sẽ không mong đợi bất kỳ lợi ích rất lớn. Hầu hết các chi phí trong IOstreams bắt nguồn từ các khu vực khác (như sử dụng các chức năng ảo), không phải do thiếu đệm.

Nếu bạn đang chạy ứng dụng này trên Windows, bạn có thể đạt được một chút bằng cách viết bộ đệm luồng của riêng mình và gọi trực tiếp số CreateFile, chuyển (ví dụ) FILE_FLAG_SEQUENTIAL_SCAN hoặc FILE_FLAG_NO_BUFFERING. Trong hoàn cảnh, một trong hai điều này có thể giúp hiệu suất của bạn đáng kể.

3

Nếu bạn muốn tốc độ thực, thì bạn sẽ phải ngừng đọc các dòng vào chuỗi std :: và bắt đầu sử dụng char* s vào bộ đệm. Cho dù bạn đọc bộ đệm đó bằng cách sử dụng ifstream::read() hoặc bộ nhớ ánh xạ tập tin là ít quan trọng, mặc dù đọc() có bất lợi bạn lưu ý về khả năng có N dòng đầy đủ và một không đầy đủ trong bộ đệm, và cần phải nhận ra rằng (có thể dễ dàng làm điều đó bằng cách quét phần còn lại của bộ đệm cho '\ n' - có lẽ bằng cách đặt NUL sau bộ đệm và sử dụng strchr). Bạn cũng sẽ cần phải sao chép một phần dòng vào đầu bộ đệm, đọc đoạn tiếp theo từ tệp để nó tiếp tục từ điểm đó và thay đổi số ký tự tối đa được đọc sao cho nó không tràn bộ đệm. Nếu bạn lo lắng về FILE *, tôi hy vọng bạn cảm thấy thoải mái với const char * ....

Vì bạn đang đề xuất điều này vì lý do hiệu suất, tôi hy vọng bạn đã định cấu hình để đảm bảo rằng nó không khai thác trường CSV của bạn, đó là nút cổ chai thực sự.

1

Tôi hy vọng điều này sẽ giúp -

http://www.cppprog.com/boost_doc/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.mapped_file

BTW, bạn đã viết "tôi thấy rất nhiều vấn đề với giải pháp như đệm có thể có những dòng đầy đủ vv .." - trong tình huống này như thế nào về đọc 250 MB và sau đó đọc char bằng char cho đến khi bạn nhận được dấu phân tách để hoàn thành dòng.

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