如何从POSIX文件描述符构造一个c ++ fstream? [英] How to construct a c++ fstream from a POSIX file descriptor?
问题描述
我基本上是在寻找一个C ++版本的fdopen()。我做了一些研究,这是一些似乎应该很容易,但事实证明是非常复杂的事情之一。我在这个信念中缺少一些东西(即它真的很容易)?
I'm basically looking for a C++ version of fdopen(). I did a bit of research on this and it is one of those things that seems like it should be easy, but turns out to be very complicated. Am I missing something in this belief (i.e. it really is easy)? If not, is there a good library out there somewhere to handle this?
编辑:将我的示例解决方案移动到一个单独的答案。
Moved my example solution to a separate answer.
推荐答案
从ÉricMalenfant给出的答案:
From the answer given by Éric Malenfant:
AFAIK没有办法这样做在
标准C ++。根据您的
平台,您的
标准库的实现可能提供(作为
非标准扩展)fstream
构造函数,以文件描述符
作为输入。 (这是
libstdc ++,IIRC的情况)或文件*。
AFAIK, there is no way to do this in standard C++. Depending on your platform, your implementation of the standard library may offer (as a nonstandard extension) a fstream constructor taking a file descriptor as input. (This is the case for libstdc++, IIRC) or a FILE*.
基于上述观察和我的研究有两个变体的工作代码;一个用于libstdc ++,另一个用于Microsoft Visual C ++。
Based on above observations and my research below there's working code in two variants; one for libstdc++ and another one for Microsoft Visual C++.
有非标准的 __ gnu_cxx :: stdio_filebuf
类模板,它继承了 std :: basic_streambuf
并具有以下构造函数
There's non-standard __gnu_cxx::stdio_filebuf
class template which inherits std::basic_streambuf
and has the following constructor
stdio_filebuf (int __fd, std::ios_base::openmode __mode, size_t __size=static_cast< size_t >(BUFSIZ))
与描述此构造函数将文件流缓冲区与打开的POSIX文件描述符相关联。
我们创建它传递POSIX句柄(行1),然后我们将它传递给istream的构造函数作为basic_streambuf(行2):
We create it passing POSIX handle (line 1) and then we pass it to istream's constructor as basic_streambuf (line 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;
}
Microsoft Visual C ++ < h1>
以前是非标准的版本 ifstream的构造函数接受POSIX文件描述符,但它从当前文档和从代码。还有另一个非标准版本的ifstream的构造函数取FILE *
Microsoft Visual C++
There used to be non-standard version of ifstream's constructor taking POSIX file descriptor but it's missing both from current docs and from code. There is another non-standard version of ifstream's constructor taking FILE*
explicit basic_ifstream(_Filet *_File)
: _Mybase(&_Filebuffer),
_Filebuffer(_File)
{ // construct with specified C stream
}
它没有记录(我甚至不能找到任何旧的文档,它会存在)。我们将其称为(第1行),参数是调用 _fdopen的结果从POSIX文件句柄中获取C流FILE *。
and it's not documented (I couldn't even find any old documentation where it would be present). We call it (line 1) with the parameter being the result of calling _fdopen to get C stream FILE* from POSIX file handle.
#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;
}
这篇关于如何从POSIX文件描述符构造一个c ++ fstream?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!