Da resposta de Éric Malenfant:
AFAIK, não há como fazer isso no C ++ padrão. Dependendo de sua plataforma, sua implementação da biblioteca padrão pode oferecer (como uma extensão não padrão) um construtor fstream tomando um descritor de arquivo como entrada. (Esse é o caso de libstdc ++, IIRC) ou um FILE *.
Com base nas observações acima e na minha pesquisa abaixo, há um código funcional em duas variantes; um para libstdc ++ e outro para Microsoft Visual C ++.
libstdc ++
Há um __gnu_cxx::stdio_filebuf
modelo de classe não padrão que herda std::basic_streambuf
e tem o seguinte construtor
stdio_filebuf (int __fd, std::ios_base::openmode __mode, size_t __size=static_cast< size_t >(BUFSIZ))
com descrição Este construtor associa um buffer de fluxo de arquivo a um descritor de arquivo POSIX aberto.
Nós o criamos passando o identificador POSIX (linha 1) e então o passamos para o construtor do istream como basic_streambuf (linha 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 ++
Costumava haver uma versão não padrão do construtor do ifstream usando o descritor de arquivo POSIX, mas está faltando nos documentos atuais e no código. Há outra versão não padrão do construtor do ifstream pegando FILE *
explicit basic_ifstream(_Filet *_File)
: _Mybase(&_Filebuffer),
_Filebuffer(_File)
{ // construct with specified C stream
}
e não está documentado (não consegui nem encontrar qualquer documentação antiga onde estivesse presente). Nós o chamamos (linha 1) com o parâmetro sendo o resultado da chamada _fdopen para obter o fluxo C FILE * do identificador de arquivo POSIX.
#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;
}