设为首页 加入收藏

TOP

15.4 双向I/O
2013-10-07 15:36:46 来源: 作者: 【 】 浏览:63
Tags:15.4 双向 I/O

15.4  双向I/O

目前,本章已经讨论了输入和输出流,讨论的时候把这两个类当做独立但又关联的类。事实上,有一种流可以同时执行输入和输出。双向流可以同时以输入流和输出流的方式操作。

双向流是iostream的子类,而iostream是istream和ostream的子类,因此这是一个多重继承的实例。跟直觉一样,双向流同时支持>>运算符和<<运算符,还支持输入流和输出流的方法。

fstream类提供了双向文件流。fstream特别适合于需要替换文件中数据的应用程序,因为可以通过读取文件找到正确的位置,然后立即切换为写入文件。例如,假设一个程序保存一个ID号和电话号码之间的映射列表。这个程序可能使用以下格式的数据文件:

  1. 123 408-555-0394  
  2. 124 415-555-3422  
  3. 164 585-555-3490  
  4. 100 650-555-3434 

一个合理的方案是当这个程序打开文件的时候读取整个数据文件,然后在程序结束的时候,将所有的变化重新写入这个文件。然而,如果数据集巨大,可能无法把所有数据都保存在内存中。如果使用iostream,则不需要这样。您可以轻松扫描文件找到记录,然后以追加模式打开输出文件来添加新记录。如果要修改已有记录,可以使用双向流,例如下面的函数替换指定ID的电话号码:
  1. bool changeNumberForID(const string& inFileName, int inID,  
  2. const string& inNewNumber)  
  3. {  
  4. fstream ioData(inFileName.c_str());  
  5. if (!ioData) {  
  6. cerr << "Error while opening file " << inFileName << endl;  
  7. return false;  
  8. }  
  9. // Loop until the end of file  
  10. while (ioData.good()) {  
  11. int id;  
  12. string number;  
  13. // Read the next ID.  
  14. ioData >> id;  
  15. // Check to see if the current record is the one being changed.  
  16. if (id == inID) {  
  17. // Seek to the current read position  
  18. ioData.seekp(ioData.tellg());  
  19. // Output a space, then the new number.  
  20. ioData << " " << inNewNumber;  
  21. break;  
  22. }  
  23. // Read the current number to advance the stream.  
  24. ioData >> number;  
  25. }  
  26. return true;  
  27. }  
  28.  
  29. 代码取自Bidirectional\Bidirectional.cpp 

当然,只有在数据大小固定的时候这种方法才能正常工作。当以上程序从读取切换到写入的时候,输出数据会改写文件中的其他数据。为了保持文件的格式,并且避免写入下一条记录,数据必须相同大小。

还可以通过stringstream类双向访问字符串流。

双向流用不同的指针保存读位置和写位置。在读取和写入之间切换的时候,需要定位到正确的位置。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇15.2 字符串流 下一篇15.5 本章小结

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)
·索引堆及其优化 - 菜 (2025-12-24 20:18:50)
·Shell 中各种括号的 (2025-12-24 19:50:39)
·Shell 变量 - 菜鸟教 (2025-12-24 19:50:37)