繁体   English   中英

对std :: ifstream表达“只读,不修改位置”

[英]Expressing “read-only, no modification of position” for std::ifstream

在我的代码中,我想确定一些有关文件内容的属性,然后再决定如何读取该文件。 (也就是说,我搜索一个关键字,如果找到,将使用foo(std::ifstream&)读取,否则使用bar(std::ifstream&)读取)。

我实现了将关键字搜索为的方法

bool containsKeyword(std::ifstream& file, const char* keyword)
{
    for ( std::string line; std::getline(file, line); )
    {
        if ( line == keyword )
        {
            return true;
        }
    }
    return false;
}

这将修改文件流的位置(如果找不到关键字,则结尾或关键字的位置)。 但是我希望在搜索后将位置重置。 这可以通过ScopeGuard来完成:

class FilePositionScopeGuard
{
   private:
      std::ifstream& file;
      using FilePosition = decltype(std::declval<std::ifstream>().tellg());
      FilePosition initial_position;
   public:
      FilePositionScopeGuard(std::ifstream& file_)
      :
         file(file_),
         initial_position(file.tellg())
      {
      }
      ~FilePositionScopeGuard()
      {
         file.clear();
         file.seekg(initial_position);
      }
};

现在我们将其添加到方法中:

bool containsKeyword(std::ifstream& file, const char* keyword)
{
    FilePositionScopeGuard guard(file);
    for ( std::string line; std::getline(file, line); )
    {
        ...

很好,因为在该方法中仅增加一行,无论该方法如何退出(返回之一或异常),我们都会得到不修改std::ifstream的行为。

但是,方法bool containsKeyword(std::ifstream&, const char*); 不表达常数 如何调整我的方法以表示(在界面级别)该方法不会更改当前状态?

您可以更改签名以获取位置保护文件:

bool containsKeyword(const FilePositionScopeGuard &, const char *);

这使调用者可以根据当前签名传递ifstream (为该操作构造一个临时保护),或者使自己成为保护程序并将其用于多个操作。

您需要使ifstream成员可公开访问。

用文本注释进行// the method does read from file but resets the read pointer

不要期望API的用户会像键盘上的猴子。 具体来说,在方法内部强制转换常量时,请勿将ifstream参数标记为const。 它确实在多线程程序中有所作为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM