CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

C++标准输入输出流库之移花接木

楼主anrxhzh(百宝箱)2002-07-04 17:05:45 在 C/C++ / C语言 提问

曾经见过一个帖子,问如何用C\C++标准输入输出库实现lock   file的功能。恰好我也碰到了类似的问题,思考了一下,觉得这是一个具有普遍意义的问题。实际上早期的标准库是支持lock   file的,后来由于兼容性的问题取消了这个功能。我们知道,每个操作系统都提供了一套文件操作的API,C\C++标准库中支持的功能只能是所有操作系统API的交集,如果我们需要这个交集以外的功能,同时又希望能最大限度地利用标准库,那么该如何做呢?  
   
  实际上,标准库任何的文件操作最终都是通过操作系统提供的API来完成的,我们只需要将库中的抽象类型和底层的FILE   HANDLE做一个一一映射就解决了这个问题,下面的文档详细地介绍了WIN32系统下如何完成映射。  
  http://www.codeproject.com/file/handles.asp  
   
  我要补充两点:  
  1.文档的方法同样适用于UNIX的文件描述符。  
  2.在抽象层和操作系统的映射的两端要分别做一次Clearup,确保提交给对方的是一个干净的对象。这样就可以保证这两个层次不会发生任何冲突。  
  问题点数:1、回复次数:8Top

1 楼anrxhzh(百宝箱)回复于 2002-07-04 21:16:15 得分 0

进一步的研究发现,只有在老的fstream中才能取得底层的文件句柄;新的C++标准库已经将句柄封装到了basic_filebuf的实现细节中,不可能得到了。结论是:如果使用了新的标准库,就不要动这种和操作系统底层移花接木的念头了。  
  Top

2 楼anrxhzh(百宝箱)回复于 2002-07-04 21:19:02 得分 0

看来只好自己写一个文件类了。  
  不如意事十八九。Top

3 楼guopo(某年某月)回复于 2002-07-04 21:26:14 得分 0

up!Top

4 楼anrxhzh(百宝箱)回复于 2002-07-04 21:43:42 得分 0

嘿嘿,还有一招,自己写一个my_fstream:public   basic_istream;估计还比较简单,因为我们需要的仅仅是保存一个操作系统文件句柄而已。如果成功了,我会将代码帖在这里,也欢迎有兴趣的朋友指点。修炼去也。  
  Top

5 楼LeeMaRS(小菜虎,仍需努力)回复于 2002-07-04 21:46:20 得分 0

自问自答?.....高人!   STRONG!  
   
  Top

6 楼anrxhzh(百宝箱)回复于 2002-07-04 23:30:37 得分 0

终于成功了。需要说明的是:  
  1.下面的例子只给出了basic_ifstream,还需要改写basic_ofstream和basic_fstream,不过是大同小异的工作。  
  2.当移植到UNIX平台时,需要改写例子中和操作系统中有关的部分。  
  3.算了算,我仅仅增加了11行代码就完成了对std::basic_ifstream的改造,这种改造对标准库是完全透明的,即使加上另外两个类也不超过50行的代码量,却获得了操作系统底层的文件句柄,使得移花接木成为可能。  
   
  #include   <fstream>  
   
  namespace   ashura   {  
   
  //   TEMPLATE   CLASS   basic_ifstream  
  template<class   _E,   class   _Tr   =   char_traits<_E>   >  
  class   basic_ifstream   :   public   std::basic_istream<_E,   _Tr>   {  
  public:  
  typedef   basic_ifstream<_E,   _Tr>   _Myt;  
  typedef   std::basic_filebuf<_E,   _Tr>   _Myfb;  
  basic_ifstream()  
  :   std::basic_istream<_E,   _Tr>(&_Fb)   {}  
   
  //explicit   basic_ifstream(const   char   *_S,  
  // std::ios_base::openmode   _M   =   in)  
  // :   std::basic_istream<_E,   _Tr>(&_Fb)  
  // {if   (_Fb.open(_S,   _M   |   in)   ==   0)  
  // setstate(failbit);   }  
   
  ///////// my   code   begin /////////  
  explicit   basic_ifstream(const   char   *_S,  
  std::ios_base::openmode   _M   =   in)  
  :   std::basic_istream<_E,   _Tr>(&_Fb),   _file(_S,   _M   |   in),   _Fb(_file.f)  
  {if   (!_file.isopen())  
  setstate(failbit);   }  
  FILE*   get_handle()   {   return   _file.f;   }  
  ///////// my   code   end /////////  
   
  virtual   ~basic_ifstream()  
  {}  
  _Myfb   *rdbuf()   const  
  {return   ((_Myfb   *)&_Fb);   }  
  bool   is_open()   const  
  {return   (_Fb.is_open());   }  
  void   open(const   char   *_S,   std::ios_base::openmode   _M   =   in)  
  {if   (_Fb.open(_S,   _M   |   in)   ==   0)  
    setstate(failbit);   }  
  void   open(const   char   *_S,   std::ios_base::open_mode   _M)  
  {open(_S,   (openmode)_M);   }  
  void   close()  
  {if   (_Fb.close()   ==   0)  
    setstate(failbit);   }  
  private:  
  ///////// my   code   begin /////////  
  struct   osfile{  
  osfile(const   char   *_S,   std::ios_base::openmode   _M)   :   f(std::__Fiopen(_S,   _M))   {   };  
  bool   isopen()   {   return   f!=0;   }  
  FILE*   f;  
  }   _file;  
  ///////// my   code   end /////////  
  _Myfb   _Fb;  
  };  
   
  typedef   basic_ifstream<char,   std::char_traits<char>   >   ifstream;  
   
  }  
   
   
  #include   <string>  
  #include   <iostream>  
  #include   <windows.h>  
  #include   <io.h>  
   
  int   main()  
  {  
  ashura::ifstream   f("c:\\test.txt");  
   
  HANDLE   hFile   =   reinterpret_cast<HANDLE>(_get_osfhandle(f.get_handle()->_file));  
  BY_HANDLE_FILE_INFORMATION   file_info;  
  BOOL   bSuccess   =   GetFileInformationByHandle(hFile,&file_info);  
   
  using   namespace   std;  
  string   str;  
  f   >>   str;  
  cout   <<   bSuccess   <<   "   "   <<   str   <<   endl;  
  }  
   
  //output:  
  //1   hello  
   
   
  Top

7 楼pi1ot(-=\Pilot/=-)回复于 2002-07-05 01:39:45 得分 1

谢谢.Top

相关问题

  • c或c++的输入输出问题
  • C++是怎么输入输出的?
  • C#中文的输入、输出????
  • 请教c/c++中输入/输出的问题
  • 输入输出
  • 问个很弱的C输入输出问题
  • c的输入输出的菜鸟问题
  • 一个C++输入输出流的问题
  • 用C语言如何实现文件的输入/输出
  • C++ Primer 的例子 有关文件输入输出的

关键词

  • c++
  • basic
  • 操作系统
  • 文件
  • 代码
  • code
  • ifstream
  • 库
  • myfb
  • 句柄

得分解答快速导航

  • 帖主:anrxhzh
  • pi1ot

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo