Tôi có thể mở ifstream
(hoặc đặt một tệp hiện có theo bất kỳ cách nào) để chỉ đọc một phần của tệp không? Ví dụ, tôi muốn có ifstream
đọc một tệp từ byte 10 đến 50. Tìm kiếm vị trí 0 sẽ là vị trí 10 trong thực tế, đọc vị trí quá khứ 40 (50 trong thực tế) sẽ lặp lại trong một EOF
, v.v. theo bất kỳ cách nào?đọc một phần của tệp bằng iostreams
Trả lời
Chắc chắn có thể thực hiện bằng cách triển khai bộ lọc luồng lọc: bạn sẽ lấy được từ std::streambuf
và lấy phạm vi bạn muốn hiển thị và bộ đệm luồng cơ bản (tốt, con trỏ đến nó) làm đối số. Sau đó, bạn sẽ tìm đến vị trí bắt đầu. Hàm underflow()
bị ghi đè sẽ đọc từ bộ đệm luồng cơ bản vào bộ đệm của nó cho đến khi đã tiêu thụ bao nhiêu ký tự như mong muốn. Dưới đây là một phiên bản hơi thô và hoàn toàn chưa được kiểm tra:
#include <streambuf>
struct rangebuf: std::streambuf {
rangebuf(std::streampos start,
size_t size,
std::streambuf* sbuf):
size_(size), sbuf_(sbuf)
{
sbuf->seekpos(start, std::ios_base::in);
}
int underflow() {
size_t r(this->sbuf_->sgetn(this->buf_,
std::min<size_t>(sizeof(this->buf_), this->size_));
this->size -= r;
this->setg(this->buf_, this->buf_, this->buf_ + r);
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*this->gptr());
}
size_t size_;
std::streambuf* sbuf_;
};
Bạn có thể sử dụng một con trỏ đến một thể hiện của bộ đệm dòng này để initialuze một std::istream
. Nếu nhu cầu định kỳ này, bạn có thể muốn tạo một lớp có nguồn gốc từ std::istream
thiết lập bộ đệm luồng thay thế.
Bạn có thể đọc các byte mà bạn muốn vào một chuỗi hoặc mảng char, sau đó bạn có thể sử dụng chuỗi đó với một istringstream, và sử dụng thay vì ifstream của bạn. Ví dụ:
std::ifstream fin("foo.txt");
fin.seekg(10);
char buffer[41];
fin.read(buffer, 40);
buffer[40] = 0;
std::istringstream iss(buffer);
for (std::string s; iss >> s;) std::cout << s << '\n';
Nếu bạn cần để xử lý tập tin nhị phân, bạn có thể làm điều đó quá:
std::ifstream fin("foo.bin", std::ios::binary | std::ios::in);
fin.seekg(10);
char buffer[40];
fin.read(buffer, 40);
std::istringstream(std::string(buffer, buffer+40));
Bạn có thể muốn thực hiện riêng lớp đọc luồng của mình (tốt nhất là thông qua một số giao diện ifstream nếu có) .
- 1. Có thể tăng cường iostreams đọc và nén các tệp được nén trên máy bay không?
- 2. Tăng iostreams: Cách tạo luồng TCP (để đọc) TCP?
- 3. Đọc một tệp MIDI bằng Python
- 4. Xóa một phần của tên tệp bằng mv
- 5. Tải xuống một phần của Tệp bằng Yêu cầu HTTP
- 6. C++ iostreams và python
- 7. đọc tệp .bmp bằng C++
- 8. Đọc tệp xlsx bằng PHP
- 9. Đọc văn bản bên trong của một phần tử XML bằng cách sử dụng Go
- 10. Cách đọc phần appSettings trong tệp web.config?
- 11. C++, đọc tệp bằng ifstream
- 12. Đọc tệp CSV bằng .NET?
- 13. Đọc tệp settings.xml của maven khi xây dựng bằng gradle?
- 14. Đọc tệp bằng máy quét Java
- 15. Cách đọc các ô trống của tệp excel bằng POI
- 16. Đọc nội dung của một tệp trong sharpsvn
- 17. Cách đọc dữ liệu của tệp Excel bằng C#?
- 18. cách đọc nội dung của tệp bằng Fileupload
- 19. Sử dụng tăng :: iostreams :: tee_device?
- 20. Deserialize một phần của tệp nhị phân
- 21. Tôi có thể đọc từng dòng bằng cách sử dụng giao diện Boost IOStreams cho các tệp Gzip như thế nào?
- 22. In ấn di động của số mũ của một đôi để C + + iostreams
- 23. Làm thế nào để đọc một tệp XML bằng Java?
- 24. Đọc một tệp ngược?
- 25. Đọc một tệp .pdb
- 26. Đọc một dòng cụ thể của một tệp
- 27. Đọc một phần của phản hồi html ajax
- 28. Cách xóa thuộc tính chỉ đọc của một tệp MFC
- 29. Đọc tệp Rùa/N3 RDF bằng Python
- 30. Cách đọc tệp từ URI bằng StreamReader?
Cần lưu ý rằng giải pháp này sẽ chỉ hoạt động với các tệp văn bản. –
@ KhaledNassar: Nó có thể dễ dàng được điều chỉnh để làm việc cho các tệp nhị phân. Làm xong. –
Một vấn đề với cách tiếp cận này là việc chờ đợi được đọc có thể khá lớn. Chắc chắn nếu nó thực sự là to lớn bạn có thể muốn chăm sóc của phạm vi separatly anyway. –