2010-10-31 15 views
15

Yine de fstream'dan (dosya) stringstream (bellekteki bir akış) verilerine veri aktarabilir miyim?Veriyi arabellek olmaksızın fstream'den stringstream'e kopyalayın?

Şu anda bir arabellek kullanıyorum, ancak bu bellekte iki katına ihtiyaç duyuyor, çünkü verileri bir arabelleğe kopyalamanız gerekiyor, ardından arabelleği arabelleğe kopyalamanız gerekiyor ve siz arabelleği silinceye kadar, veriler çoğaltıyor hafızada.

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;` 

kimse ben bir İnbetween tampon kullanmadan bir stringstream için bütün dosyası yazmak nasıl biliyor mu?

+0

ne anlamı var: Burada

(derlenmiş ve test edilmiş) bir örnek kullanımıdır? Verimi geliştirmeye mi çalışıyorsunuz? Muhtemelen fstream'i fışkırtmak zorunda kalacaksınız, bu durumda iostreams SLOW. Bellek ayak izinizi azaltmaya mı çalışıyorsunuz? Dosyayı bir kerede değil, yığın halinde okumak buna yardımcı olabilir. –

cevap

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

Bu, dosyayı 'ifstream' arabelleğine hala okuyor. –

+0

Orijinal koddan daha az bir arabellektir. –

+0

@Charles - Yine de, bu onun istediği şey olduğunu düşünüyorum. Yeni bir char dizisi tahsis etmek istemedi. Fstream nesnesinden doğrudan stringstream nesnesine okumak istedi. –

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

C++ standart kütüphane kullanılarak tek yolu ostrstream yerine stringstream arasında kullanmaktır.

Kendi char tamponunuzla bir ostrstream nesnesini oluşturabilir ve daha sonra arabelleğin sahipliğini alır (böylece daha fazla kopyalama gerekmez).

Ancak, strstream başlığının kullanımdan kaldırıldığını unutmayın (hala C++ 03'in bir parçası olmasına rağmen, büyük olasılıkla standart kitaplık uygulamalarının çoğunda kullanılabilir) ve unutursanız büyük sorunlara girersiniz. ostrstream'e sağlanan veriyi sonlandırmak için kullanılır. Bu, akış operatörleri için de geçerlidir, örneğin: ostrstreamobject << some_data << std::ends; (std::ends, verileri sıfırlar).

7

ostream belgelerinde, several overloads for operator<< vardır. Bunlardan biri bir streambuf* alır ve tüm streambuffer içeriğini okur.

#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); 
}