Từ câu trả lời của Éric Malenfant:
AFAIK, không có cách nào để làm điều này trong C ++ tiêu chuẩn. Tùy thuộc vào nền tảng của bạn, việc triển khai thư viện chuẩn của bạn có thể cung cấp (như một phần mở rộng không chuẩn) một hàm tạo fstream lấy một bộ mô tả tệp làm đầu vào. (Đây là trường hợp của libstdc ++, IIRC) hoặc FILE *.
Dựa trên những quan sát ở trên và nghiên cứu của tôi bên dưới, có mã hoạt động trong hai biến thể; một cho libstdc ++ và một cho Microsoft Visual C ++.
libstdc ++
Có __gnu_cxx::stdio_filebuf
mẫu lớp không chuẩn kế thừa std::basic_streambuf
và có hàm tạo sau
stdio_filebuf (int __fd, std::ios_base::openmode __mode, size_t __size=static_cast< size_t >(BUFSIZ))
với mô tả Hàm khởi tạo này liên kết bộ đệm dòng tệp với bộ mô tả tệp POSIX đang mở.
Chúng tôi tạo nó thông qua xử lý POSIX (dòng 1) và sau đó chúng tôi chuyển nó đến hàm tạo của istream dưới dạng basic_streambuf (dòng 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 ++
Đã từng có phiên bản không chuẩn của hàm tạo của ifstream lấy bộ mô tả tệp POSIX nhưng nó bị thiếu cả trong tài liệu hiện tại và từ mã. Có một phiên bản không chuẩn khác của phương thức khởi tạo ifstream lấy FILE *
explicit basic_ifstream(_Filet *_File)
: _Mybase(&_Filebuffer),
_Filebuffer(_File)
{ // construct with specified C stream
}
và nó không được ghi lại (tôi thậm chí không thể tìm thấy bất kỳ tài liệu cũ nào mà nó sẽ có mặt). Chúng tôi gọi nó (dòng 1) với tham số là kết quả của việc gọi _fdopen để lấy C luồng FILE * từ tay cầm tệp 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;
}