使用 C++ 和 RAII 读取文件

ant*_*tor 3 c++ raii

使用 C++ 和 RAII 读取文件的最佳方法是什么?我见过的所有示例都使用类似于以下代码的内容:

#include <iostream>
#include <fstream>

int main () {

  std::ifstream is ("test.txt", std::ifstream::binary);
  if (is) {
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);

    char * buffer = new char [length]; // Seems wrong?

    is.read (buffer, length);

    delete[] buffer;
  }
}
Run Code Online (Sandbox Code Playgroud)

根据我对 RAII 的了解,初始化 char 指针并手动删除它似乎是错误的。

我做过类似的事情:

#include <iostream>
#include <fstream>

int main () {

  std::ifstream is ("test.txt", std::ifstream::binary);
  if (is) {
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);

    std::shared_ptr<char> buffer = std::make_shared<char>();

    is.read (buffer.get(), length);
  }
}
Run Code Online (Sandbox Code Playgroud)

但我也不确定这是否正确。如果需要的话(或者如果可能,或者它是否有意义?),我也无法成功地转换std::shared_ptr<char>为 a 。std::shared_ptr<uint8_t>

utn*_*tim 5

char * buffer = new char [长度]; // 好像错了?

这没有错,只是……不安全。

更安全的实施:

std::unique_ptr<char[]> buffer{new char [length]}; // note: use char[] as parameter
is.read (buffer.get(), length);
Run Code Online (Sandbox Code Playgroud)

比以前更好:

std::vector<char> buffer{length, ' '};
is.read (buffer.data(), length);
Run Code Online (Sandbox Code Playgroud)

或者:

std::string buffer{length, ' '};
is.read (buffer.data(), length);
Run Code Online (Sandbox Code Playgroud)

特别是,这是未定义的行为:

std::shared_ptr<char> buffer = std::make_shared<char>();
is.read (buffer, length);
Run Code Online (Sandbox Code Playgroud)

因为它动态分配一个字符,然后在该内存位置放置最多 length 个字符。实际上,这是缓冲区溢出,除非您的长度始终为 1。