c - studio - ¿Hay un equivalente de Windows para fdopen para HANDLEs?
visual studio code para c (1)
Desafortunadamente, HANDLE
s son bestias completamente diferentes de FILE*
sy descriptores de archivos. En última instancia, el CRT maneja los archivos en términos de HANDLE
y asocia esos HANDLE
a un descriptor de archivo. Esos descriptores de archivo a su vez retrocede el puntero de estructura por FILE*
.
Afortunadamente, hay una sección en esta página MSDN que describe las funciones que "proporcionan una forma de cambiar la representación del archivo entre una estructura FILE , un descriptor de archivo y un identificador de archivo Win32":
_fdopen
,_wfdopen
: asocia una secuencia con un archivo que se abrió previamente para E / S de bajo nivel y devuelve un puntero a la secuencia abierta._fileno
: Obtiene el descriptor de archivo asociado a una secuencia._get_osfhandle
: devolver el identificador de archivo del sistema operativo asociado con el descriptor de archivo C en tiempo de ejecución existente_open_osfhandle
:_open_osfhandle
archivo de tiempo de ejecución de Associates C con un identificador de archivo de sistema operativo existente.
Parece que lo que necesitas es _open_osfhandle
seguido de _fdopen
para obtener un FILE*
de un HANDLE
.
Aquí hay un ejemplo de HANDLE
s obtenido de CreateFile()
. Cuando lo probé, muestra los primeros 255 caracteres del archivo "test.txt" y agrega "--- Hello World! ---" al final del archivo:
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <cstdio>
int main()
{
HANDLE h = CreateFile("test.txt", GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(h != INVALID_HANDLE_VALUE)
{
int fd = _open_osfhandle((intptr_t)h, _O_APPEND | _O_RDONLY);
if(fd != -1)
{
FILE* f = _fdopen(fd, "a+");
if(f != 0)
{
char rbuffer[256];
memset(rbuffer, 0, 256);
fread(rbuffer, 1, 255, f);
printf("read: %s/n", rbuffer);
fseek(f, 0, SEEK_CUR); // Switch from read to write
const char* wbuffer = " --- Hello World! --- /n";
fwrite(wbuffer, 1, strlen(wbuffer), f);
fclose(f); // Also calls _close()
}
else
{
_close(fd); // Also calls CloseHandle()
}
}
else
{
CloseHandle(h);
}
}
}
Esto debería funcionar también para tuberías.
En Unix, si tiene un descriptor de archivo (por ejemplo, desde un socket, pipe o hereditario de su proceso principal), puede abrir un flujo de E / S FILE*
en fdopen(3)
con fdopen(3)
.
¿Hay un equivalente en Windows para HANDLE
s? Si tiene un HANDLE
que se heredó de su proceso principal (diferente de stdin, stdout o stderr) o un conducto de CreatePipe
, ¿es posible obtener un flujo de FILE*
almacenado en él? MSDN documenta _fdopen
, pero funciona con descriptores de archivos enteros devueltos por _open
, no _open
genéricas.