如何从 POSIX 文件描述符构造 ac fstream?

新手上路,请多包涵

我基本上是在寻找 fdopen() 的 C++ 版本。我对此进行了一些研究,这是其中似乎应该很容易的事情之一,但结果却非常复杂。我是否在这种信念中遗漏了一些东西(即它真的很容易)?如果没有,是否有一个好的图书馆可以处理这个问题?

编辑:将我的示例解决方案移至单独的答案。

原文由 BD at Rivenhill 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 772
2 个回答

从Éric Malenfant给出的答案:

AFAIK,在标准 C++ 中没有办法做到这一点。根据您的平台,您的标准库实现可能会提供(作为非标准扩展)一个 fstream 构造函数,将文件描述符作为输入。 (libstdc++、IIRC 就是这种情况)或 FILE*。

基于上述观察和我在下面的研究,有两种变体的工作代码;一个用于 libstdc++,另一个用于 Microsoft Visual C++。


libstdc++

有非标准 __gnu_cxx::stdio_filebuf 继承 std::basic_streambuf —的类模板并具有以下构造函数

stdio_filebuf (int __fd, std::ios_base::openmode __mode, size_t __size=static_cast< size_t >(BUFSIZ))

带描述 此构造函数将文件流缓冲区与打开的 POSIX 文件描述符相关联。

我们通过 POSIX 句柄(第 1 行)创建它,然后将其作为 basic_streambuf 传递给 istream 的构造函数(第 2 行):

 #include <ext/stdio_filebuf.h>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ofstream ofs("test.txt");
    ofs << "Writing to a basic_ofstream object..." << endl;
    ofs.close();

    int posix_handle = fileno(::fopen("test.txt", "r"));

    __gnu_cxx::stdio_filebuf<char> filebuf(posix_handle, std::ios::in); // 1
    istream is(&filebuf); // 2

    string line;
    getline(is, line);
    cout << "line: " << line << std::endl;
    return 0;
}


微软视觉 C++

曾经有非标准 版本 的 ifstream 构造函数采用 POSIX 文件描述符,但 当前 文档和代码都缺少它。 ifstream 构造函数的另一个非标准版本采用 FILE*

 explicit basic_ifstream(_Filet *_File)
    : _Mybase(&_Filebuffer),
        _Filebuffer(_File)
    {   // construct with specified C stream
    }

并且没有记录(我什至找不到任何旧文档)。我们调用它(第 1 行),参数是调用 _fdopen 以从 POSIX 文件句柄获取 C 流 FILE* 的结果。

 #include <cstdio>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    ofstream ofs("test.txt");
    ofs << "Writing to a basic_ofstream object..." << endl;
    ofs.close();

    int posix_handle = ::_fileno(::fopen("test.txt", "r"));

    ifstream ifs(::_fdopen(posix_handle, "r")); // 1

    string line;
    getline(ifs, line);
    ifs.close();
    cout << "line: " << line << endl;
    return 0;
}

原文由 Piotr Dobrogost 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题