Saltar al contenido

¿Cómo construir un fstream c ++ a partir de un descriptor de archivo POSIX?

Esta noticia ha sido probado por nuestros expertos así garantizamos la veracidad de esta noticia.

Solución:

De la respuesta dada por Éric Malenfant:

AFAIK, no hay forma de hacer esto en C++ estándar. Dependiendo de su plataforma, su implementación de la biblioteca estándar puede ofrecer (como una extensión no estándar) un constructor fstream que toma un descriptor de archivo como entrada. (Este es el caso de libstdc++, IIRC) o un ARCHIVO*.

Según las observaciones anteriores y mi investigación a continuación, hay un código de trabajo en dos variantes; uno para libstdc++ y otro para Microsoft Visual C++.


libstdc++

No es estándar __gnu_cxx::stdio_filebuf plantilla de clase que hereda std::basic_streambuf y tiene el siguiente constructor

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

con descripción Este constructor asocia un búfer de flujo de archivos con un descriptor de archivo POSIX abierto.

Lo creamos pasando el identificador POSIX (línea 1) y luego lo pasamos al constructor de istream como basic_streambuf (línea 2):

#include 
#include 
#include 
#include 

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 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++

Solía ​​​​haber una versión no estándar del constructor de ifstream que tomaba el descriptor de archivo POSIX, pero falta tanto en los documentos actuales como en el código. Hay otra versión no estándar del constructor de ifstream que toma ARCHIVO*

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

y no está documentado (ni siquiera pude encontrar ninguna documentación antigua donde estaría presente). Lo llamamos (línea 1) y el parámetro es el resultado de llamar a _fdopen para obtener C stream FILE* del identificador de archivo POSIX.

#include 
#include 
#include 
#include 

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;

AFAIK, no hay forma de hacer esto en C++ estándar. Dependiendo de su plataforma, su implementación de la biblioteca estándar puede ofrecer (como una extensión no estándar) un constructor fstream que toma un descriptor de archivo (Este es el caso de libstdc++, IIRC) o un FILE* como entrada.

Otra alternativa sería usar un dispositivo boost::iostreams::file_descriptor, que podría envolver en un boost::iostreams::stream si desea tener una interfaz std::stream.

Es muy probable que su compilador ofrezca un constructor fstream basado en ARCHIVOS, aunque no sea estándar. Por ejemplo:

FILE* f = fdopen(my_fd, "a");
std::fstream fstr(f);
fstr << "Greetingsn";

Pero hasta donde yo sé, no hay una forma portátil de hacer esto.

Sección de Reseñas y Valoraciones

Agradecemos que quieras añadir valor a nuestro contenido dando tu veteranía en las críticas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *