З відповіді Еріка Маленфанта:
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), а потім передаємо його до конструктора istream як basic_streambuf (рядок 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 ++
Раніше нестандартна версія конструктора ifstream приймала дескриптор файлу POSIX, але він відсутній як у поточних документах, так і в коді. Існує ще одна нестандартна версія конструктора ifstream, що приймає FILE *
explicit basic_ifstream(_Filet *_File)
: _Mybase(&_Filebuffer),
_Filebuffer(_File)
{ // construct with specified C stream
}
і це не задокументовано (я навіть не міг знайти жодної старої документації, де вона була б присутня). Ми називаємо це (рядок 1), параметр є результатом виклику _fdopen для отримання потоку C FILE * з обробки файлів 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;
}