子弹 の VISIONS

NEVER back down ~~

C++博客 首页 新随笔 联系 聚合 管理
  112 Posts :: 34 Stories :: 99 Comments :: 0 Trackbacks

// created by ztwaker on 2006-8-24

// Used for: Read in the whole file

//

 

#include < iostream >

#include < fstream >

#include < string >

 

bool open ( const std :: string & fn , std :: string & data )

{

       std :: ifstream file ( fn . c_str (), std :: ios :: in | std :: ios :: binary );

       if (! file )

              return false ;

      

       file . seekg (0, std :: ios_base :: end );

       long len = file . tellg ();

       file . seekg (0, std :: ios_base :: beg );

      

       char * buffer = new char [ len ];

       file . read ( buffer , len );

       data . assign ( buffer , len );

       delete [] buffer ;

      

       file . close ();

    return true ;

}

 

void test()

{

       using namespace std ;

       const string filename = "Cpp1.ncb" ; //"Cpp22.cpp";

       string s ;

       if ( open ( filename , s ))

              cout << s . size () << endl << s . c_str () << endl ;

}

 

int main()

{

    test();

    return 0;

}

 

/*

OUTPUT:

 

33792

Microsoft C/C++ program database 2.00

.JG

*/

posted on 2006-08-24 12:22 子弹のVISIONS 阅读(2111) 评论(6)  编辑 收藏 引用

Feedback

# re: [OPPD] 一次性把整个文件读到std::string 2006-08-24 15:37 周星星
为了得到一个文件名称,而使用string不是一个好主意,建议你使用const char*,以降低依赖
使用string存储二进制数据也是非常危险的,建议你使用vector<char>
使用long存储tellg()的返回值?我建议你还是使用标准的,另外你还得考虑大于2G/4G的文件
开辟一个buffer,把文件内容读到buffer中,再由buffer存到data中,为什么不直接把文件内容读到data中?另外你还得考虑,new是否能成功

我写段代码你帮我看看
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
using namespace std;

int main()
{
const char* filename = "d:\\file.txt";

// 和你的功能一样,把文件内容读到一个容器中
{
ifstream file( filename, ios_base::binary|ios_base::in );
if( !file ) return -1;

vector<char> data;
copy( istreambuf_iterator<char>(file), istreambuf_iterator<char>(), back_inserter(data) );
}

// 把文件内容读到一个新文件中
{
ifstream file1( filename, ios_base::binary|ios_base::in );
if( !file1 ) return -1;
ofstream file2( "d:\\file2.txt", ios_base::binary|ios_base::out );
if( !file2 ) return -1;

copy( istreambuf_iterator<char>(file1), istreambuf_iterator<char>(), ostreambuf_iterator<char>(file2) );
}
}
  回复  更多评论
  

# re: [OPPD] 一次性把整个文件读到std::string 2006-08-25 09:11 子弹
@周星星

认真读了星兄的回复,觉得受益非浅。

你说得对,为了一个文件名而使用string确实不是好主意;另:
我在编码的时候只考虑怎么实现而没有顾及其他的方方面面(比如:健壮性、鲁棒性、性能等)——这是我的一个不好的习惯。
无论怎么说,都应该用std::ios::pos_type而不是long——我是想ftell返回long,就想当然用了long……

"直接把文件内容读到data中" is a good idea .

……要走的路还很长……:)

希望星兄多来指引指引小弟,非常感谢
  回复  更多评论
  

# re: [OPPD] 一次性把整个文件读到std::string 2006-08-28 11:50 子弹
参考《Effective STL》条款5和条款6,我重写为以下函数:

bool readTheWholeFile(const char* fn, std::vector<char>& data)
{
std::ifstream file(fn, std::ios_base::in | std::ios_base::binary);
if ( !file ) return false;
std::istreambuf_iterator<char> dataBegin(file);
std::istreambuf_iterator<char> dataEnd;
data.assign(dataBegin, dataEnd);
file.close();
return true;
}
  回复  更多评论
  

# re: [OPPD] 一次性把整个文件读到std::string 2007-01-05 19:35 哈胖头
一行代码就足够了。不过不提倡这种方法。

string s;

copy(istreambuf_iterator<char>(ifstream("hello.txt").rdbuf()), istreambuf_iterator<char>(), back_inserter(s));  回复  更多评论
  

# re: [OPPD] 一次性把整个文件读到std::string 2008-09-28 11:45 soli
学习了  回复  更多评论
  

# re: [OPPD] 一次性把整个文件读到std::string 2008-09-28 12:19 soli
@哈胖头
std::string 没有push_back方法,所以back_inserter(s)是不对的

  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理