简体   繁体   English

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

[英]Convert FILE* to ifstream C++, Android NDK

I'm coding an Android project with an NDK C++ component and have a file that needs a lot of parsing. 我正在编写一个带有NDK C ++组件的Android项目,并且有一个需要大量解析的文件。 The NDK only allows me to get a FILE* pointer to the file that I'm dealing with, not an ifstream which has a few more convenience functions associated with it. NDK只允许我获取一个指向我正在处理的文件的FILE *指针,而不是一个ifstream,它有一些与之相关的便利功能。 Is there anyway to convert an FILE* (cstdio) to ifstream (iostream)? 无论如何将FILE *(cstdio)转换为ifstream(iostream)?

In general, you can not convert a FILE* to an std::ifstream . 通常,您不能FILE*转换为std::ifstream However, this isn't really necessary anyway: It is reasonable straight forward to create a custom stream buffer which can be used to initialize an std::istream . 但是,这无论如何都不是必需的:创建一个可用于初始化std::istream的自定义流缓冲区是合理的。 Using an std::istream should be sufficient because the extra functionality provided by std::ifstream doesn't really help with parsing anyway. 使用std::istream应该足够了,因为std::ifstream提供的额外功能无论如何都不能真正帮助解析。 As long as you don't need to use seeking, creating a stream buffer for reading from a FILE* is really simple. 只要您不需要使用搜索,创建用于从FILE*读取的流缓冲区就非常简单。 All it takes is overriding the the std::streambuf::underflow() function: 所需要的只是覆盖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());
    }
};

All what remains is to initialize an std::istream to use a stdiobuf : 剩下的就是初始化std::istream以使用stdiobuf

stdiobuf     sbuf(fopen(...));
std::istream in(&sbuf);

I just typed in the above code and currently I can't try it out. 我只输入上面的代码,目前我无法尝试。 However, the basic should be correct although there may be types and possibly even a little flaw. 然而,基本应该是正确的,虽然可能有类型,甚至可能有一点缺陷。

Note there isn't a way to retrieve an std::ifstream , but you can get std::istream . 注意,没有办法检索std::ifstream ,但你可以得到std::istream

Though not a part of standard C++, sometimes std::basic_filebuf exposes an extension via a constructor which takes std::FILE * . 虽然不是标准C ++的一部分,但有时std::basic_filebuf通过构造函数公开扩展,该构造函数采用std::FILE *

 basic_filebuf(FILE *fp, char_type *buf = 0, streamsize n = /* default size */); 

Constructs an object of class basic_filebuf , initializing the base class with basic_streambuf<charT,traits>() . 构造类basic_filebuf的对象,使用basic_streambuf<charT,traits>()初始化基类。 It then calls open(fp, buf, n) . 然后调用open(fp, buf, n)

The way you should use this is as follows... 你应该使用它的方式如下......

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

Now, if this extension is not available, then I'm afraid there's not much you can do other than try to implement your own std::streambuf which implements the required work. 现在,如果没有这个扩展,那么我担心除了尝试实现你自己的std::streambuf以实现所需的工作之外std::streambuf他法。

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

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