2009-10-27 31 views
6

Có cách nào tốt hơn để xác định độ dài của một std :: istream hơn như sau:Cách tốt hơn để xác định chiều dài của một tiêu chuẩn :: istream?

std::istream* pcStream = GetSomeStream(); 
pcStream->seekg(0, ios::end); 
unsigned int uiLength = pcStream->tellg(); 

Nó chỉ có vẻ thực sự lãng phí phải tìm cách kết thúc của dòng và sau đó tìm cách trở lại với bản gốc vị trí, đặc biệt nếu luồng có thể là một tệp trên một số phương tiện chậm như CD hoặc DVD.

+0

Tại sao bạn cần độ dài? – sbi

+0

API tôi đang sử dụng yêu cầu kích thước của dữ liệu tôi đang chuyển. Nó sử dụng một bộ đệm ký tự thô, và tiếp tục xử lý nó cho đến khi nó đến cuối bộ đệm. – FlintZA

+0

Bạn có thể sử dụng 'stat()' trên tệp. Tuy nhiên, nó không phải là bất kỳ nhanh hơn tìm kiếm ở cuối và tìm kiếm lại ở đầu trước khi đọc nội dung ... đó là cách mô tả tập tin được thực hiện. Tất nhiên, 'stat()' không phải là C++ và nó đòi hỏi một tên tập tin ... –

Trả lời

7

Các "tốt nhất" Cách thứ nhất là để tránh cần chiều dài :)

  • Không phải tất cả con suối là seekable (Ví dụ, hãy tưởng tượng một istream trên một ổ cắm mạng)
  • Kiểu trả về từ tellg() không nhất thiết phải là số (yêu cầu duy nhất là nó có thể được trả lại cho hàm seekg() để trở về cùng một vị trí)
  • Thậm chí nếu nó là số, nó không nhất thiết là số byte. Ví dụ, nó có thể là một "kỳ diệu" giá trị có nghĩa là "ở phần cuối"
  • cho fstreams, các vấn đề như vụ án và chuyển đổi linefeed thể vít những thứ lên
+0

Tôi nhận ra rằng mong đợi một chiều dài luôn luôn có sẵn là một chút hạn chế đối với loại luồng sẽ được sử dụng, may mắn là rất khó đang sử dụng bất kỳ thứ gì khác sau đó ifstream và triển khai nguồn lưu trữ của riêng tôi và zipstream. – FlintZA

+0

Dường như kiểu trả về từ tellg() luôn là số, dựa trên [ràng buộc của std :: streampos] (http://stackoverflow.com/a/24437482/145173). –

-1

Bạn đã coi việc theo dõi kích thước bằng cách sử dụng istream :: gcount()?

+1

Tôi yêu cầu kích thước để phân bổ bộ đệm mà dữ liệu sẽ được sao chép - Tôi cho rằng tôi có thể phân bổ số tiền ban đầu và realloc sau đó, nhưng tôi hơi lo lắng về phân mảnh (hoạt động trong môi trường có giới hạn). – FlintZA

-1

Có một số loại luồng không thể có độ dài bằng cách gọi tellg(). Trong trường hợp, tellg() có thể trả lại -1.

Bạn có thể nhận được độ dài luồng bằng cách chuẩn bị đủ bộ đệm có kích thước. Tôi phát hiện ra cách để có được chiều dài bằng cách nhìn vào chức năng stream::read.

const int DATA_SIZE = 1024 * 512; 
char buf[DATA_SIZE]; // 1024 * 512 is enough! 
std::istream& is = GetSomeStream(); 
int Len = is.rdbuf()->sgetn(buf, DATA_SIZE); 

Ở trên, Len là kích thước dữ liệu thực trong istream.

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