2010-10-31 39 views
15

Tôi có thể truyền dữ liệu từ số fstream (tệp) đến stringstream (luồng trong bộ nhớ) không?Sao chép dữ liệu từ fstream đến stringstream mà không có bộ đệm?

Hiện tại, tôi đang sử dụng bộ đệm, nhưng điều này đòi hỏi gấp đôi bộ nhớ, vì bạn cần sao chép dữ liệu vào bộ đệm, sau đó sao chép bộ đệm vào chuỗi và cho đến khi bạn xóa bộ đệm, dữ liệu được sao chép trong bộ nhớ.

std::fstream fWrite(fName,std::ios::binary | std::ios::in | std::ios::out); 
    fWrite.seekg(0,std::ios::end); //Seek to the end 
    int fLen = fWrite.tellg(); //Get length of file 
    fWrite.seekg(0,std::ios::beg); //Seek back to beginning 
    char* fileBuffer = new char[fLen]; 
    fWrite.read(fileBuffer,fLen); 
    Write(fileBuffer,fLen); //This writes the buffer to the stringstream 
    delete fileBuffer;` 

Có ai biết cách tôi có thể viết toàn bộ tệp vào chuỗi mà không sử dụng bộ đệm đệm giữa không?

+0

điểm là gì? Bạn đang cố gắng cải thiện thông lượng? Bạn có thể sẽ cần phải mương 'fstream' trong trường hợp đó, iostreams là SLOW. Bạn đang cố giảm dung lượng bộ nhớ của mình? Đọc tập tin theo khối thay vì tất cả cùng một lúc có thể giúp với điều đó. –

Trả lời

25
// need to include <algorithm> and <iterator>, and of course <fstream> and <sstream> 
ifstream fin("input.txt"); 
ostringstream sout; 
copy(istreambuf_iterator<char>(fin), 
    istreambuf_iterator<char>(), 
    ostreambuf_iterator<char>(sout)); 
+0

Điều này vẫn đang đọc tệp vào bộ đệm 'ifstream'. –

+0

Đó là một bộ đệm nhỏ hơn mã gốc. –

+0

@Charles - Tuy nhiên, tôi nghĩ rằng đây là những gì ông dự định. Anh ta không muốn phân bổ một mảng char mới. Anh ta muốn đọc trực tiếp từ đối tượng fstream đến đối tượng stringstream. –

20
ifstream f(fName); 
stringstream s; 
if (f) { 
    s << f.rdbuf();  
    f.close(); 
} 
1

Cách duy nhất sử dụng thư viện chuẩn C++ là sử dụng một ostrstream thay vì stringstream.

Bạn có thể tạo đối tượng ostrstream với bộ đệm char của riêng mình và nó sẽ sở hữu bộ đệm sau đó (vì vậy không cần sao chép nữa). Tuy nhiên,

Lưu ý rằng tiêu đề strstream không còn được dùng nữa (mặc dù vẫn là phần C++ 03 và rất có thể, nó sẽ luôn sẵn có trên hầu hết các triển khai thư viện chuẩn) và bạn sẽ gặp rắc rối lớn nếu bạn quên để vô hiệu hóa dữ liệu được cung cấp cho ostrstream.Điều này cũng áp dụng cho các toán tử luồng, ví dụ: ostrstreamobject << some_data << std::ends; (std::ends hủy bỏ dữ liệu).

7

Trong tài liệu cho ostream, có several overloads for operator<<. Một trong số họ mất một số streambuf* và đọc tất cả nội dung của bộ lọc luồng.

Dưới đây là một sử dụng mẫu (biên soạn và thử nghiệm):

#include <exception> 
#include <iostream> 
#include <fstream> 
#include <sstream> 

int main (int, char **) 
try 
{ 
     // Will hold file contents. 
    std::stringstream contents; 

     // Open the file for the shortest time possible. 
    { std::ifstream file("/path/to/file", std::ios::binary); 

      // Make sure we have something to read. 
     if (!file.is_open()) { 
      throw (std::exception("Could not open file.")); 
     } 

      // Copy contents "as efficiently as possible". 
     contents << file.rdbuf(); 
    } 

     // Do something "useful" with the file contents. 
    std::cout << contents.rdbuf(); 
} 
catch (const std::exception& error) 
{ 
    std::cerr << error.what() << std::endl; 
    return (EXIT_FAILURE); 
} 
Các vấn đề liên quan