将FILE*转换为ifstream C++,Android NDK

spa*_*der 3 c++ android file android-ndk

我正在编写一个带有NDK C++组件的Android项目,并且有一个需要大量解析的文件.NDK只允许我获取一个指向我正在处理的文件的FILE*指针,而不是一个ifstream,它有一些与之相关的便利功能.无论如何将FILE*(cstdio)转换为ifstream(iostream)?

Die*_*ühl 5

通常,您无法将a转换FILE*std::ifstream.但是,这无论如何都不是必需的:创建一个可用于初始化的自定义流缓冲区是合理的std::istream.使用an std::istream应该足够了,因为提供的额外功能std::ifstream无论如何都不能真正帮助解析.只要您不需要使用搜索,创建一个用于从a读取的流缓冲区FILE*就非常简单.所需要的只是覆盖std::streambuf::underflow()功能:

class stdiobuf
    : std::streambuf
{
private:
    FILE* d_file;
    char  d_buffer[8192];
public:
    stdiobuf(FILE* file): d_file(file) {}
    ~stdiobuf() { if (this->d_file) fclose(this->d_file); }
    int underflow() {
        if (this->gptr() == this->egptr() && this->d_file) {
            size_t size = fread(this->d_file, 8192);
            this->setg(this->d_buffer, this->d_buffer, this->d_buffer + size);
        }
        return this->gptr() == this->egptr()
            ? traits_type::eof()
            : traits_type::to_int_type(*this->gptr());
    }
};
Run Code Online (Sandbox Code Playgroud)

剩下的就是初始化一个std::istream使用stdiobuf:

stdiobuf     sbuf(fopen(...));
std::istream in(&sbuf);
Run Code Online (Sandbox Code Playgroud)

我只输入上面的代码,目前我无法尝试.然而,基本应该是正确的,虽然可能有类型,甚至可能有一点缺陷.


old*_*inb 3

请注意,没有办法检索std::ifstream,但您可以获取std::istream

虽然不是标准 C++ 的一部分,但有时std::basic_filebuf通过采用.std::FILE *

basic_filebuf(FILE *fp, char_type *buf = 0, 
              streamsize n = /* default size */);
Run Code Online (Sandbox Code Playgroud)

构造一个类的对象basic_filebuf,用 初始化基类basic_streambuf<charT,traits>()。然后它调用open(fp, buf, n).

您应该使用它的方式如下......

FILE *pf = ...; /* e.g. fopen("/etc/passwd", "r") */
std::filebuf buf(pf);
std::istream stream(&buf);
Run Code Online (Sandbox Code Playgroud)

std::streambuf现在,如果此扩展不可用,那么除了尝试实现自己的扩展来实现所需的工作之外,恐怕您无能为力。