¿Qué es exactamente streambuf? ¿Como lo uso?

80

Estoy tratando de aprender un poco más sobre cómo funcionan los flujos de E / S en C ++, y estoy realmente confundido sobre cuándo usar qué.

¿Qué es exactamente un streambuf?
¿Cuándo utilizo a streambuf, en comparación con a string, an istreamo a vector? (Ya conozco los últimos tres, pero no cómo se streambufcomparan con ellos, si es que los conozco ).

usuario541686
fuente
Es una mala abstracción de un búfer de flujo.
Pubby
1
@Pubby: Er, ¿qué es un "búfer de flujo"? ¿En qué se diferencia de una secuencia o un búfer?
user541686
3
@moshbear: Lo siento, no tengo idea de a qué se refiere.
user541686
1
El lenguaje de programación C ++ de
moshbear
5
Si eso te va a hacer sentir mejor, he trabajado con C ++ durante 15 años y todavía no obtengo la parte IO de la biblioteca de C ++. No hubo un solo proyecto en el que tuviera la oportunidad de usarlo.
Nemanja Trifunovic

Respuestas:

50

Los búferes de flujo representan dispositivos de entrada o salida y proporcionan una interfaz de bajo nivel para E / S sin formato a ese dispositivo. Los flujos, por otro lado, proporcionan una envoltura de nivel superior alrededor del búfer mediante funciones de E / S básicas sin formato y, especialmente, mediante funciones de E / S formateadas (es decir, operator<<y operator>>sobrecargas). Los objetos de flujo también pueden administrar la vida útil de un búfer de flujo.

Por ejemplo, una secuencia de archivos tiene un búfer de secuencia de archivos interno. La secuencia administra la vida útil del búfer y el búfer es lo que proporciona capacidades reales de lectura y escritura a un archivo. Los operadores de formato de la secuencia acceden en última instancia a las funciones de E / S sin formato del búfer de secuencia, por lo que solo tiene que utilizar las funciones de E / S de la secuencia y no es necesario tocar las funciones de E / S del búfer directamente.

Otra forma de comprender las diferencias es observar los diferentes usos que hacen de los objetos de configuración regional. Las transmisiones utilizan las facetas que tienen que ver con el formato, como numpunctynum_get . También puede esperar que las sobrecargas de transmisión operator<<y operator>>los tipos de datos personalizados de tiempo o dinero utilicen las facetas de formato de tiempo y dinero. Los búferes de flujo, sin embargo, usan las facetas codecvt para convertir entre las unidades que usa su interfaz y los bytes. Entonces, por ejemplo, la interfaz para basic_streambuf<char16_t>usos char16_ty, por lo tanto, basic_streambuf<char16_t>utiliza internamente codecvt<char16_t, char, mbstate_t>de forma predeterminada para convertir las char16_tunidades formateadas escritas en el búfer acharunidades escritas en el dispositivo subyacente. Por lo tanto, puede ver que las transmisiones son principalmente para formatear y los búferes de transmisión brindan una interfaz de bajo nivel para la entrada o salida sin formato a dispositivos que pueden usar una codificación externa diferente.

Puede utilizar un búfer de flujo cuando solo desee acceso sin formato a un dispositivo de E / S. También puede utilizar búferes de transmisión si desea configurar varias transmisiones que compartan un búfer de transmisión (aunque tendrá que administrar cuidadosamente la vida útil del búfer). También hay búferes de flujo de propósito especial que podría querer usar, como wbuffer_converten C ++ 11, que actúa como una fachada para basic_streambuf<char>que parezca un búfer de flujo de caracteres ancho. Utiliza la faceta codecvt con la que está construida en lugar de utilizar la faceta codecvt adjunta a cualquier configuración regional. Por lo general, puede lograr el mismo efecto simplemente utilizando un búfer de flujo amplio imbuido de una configuración regional que tenga la faceta adecuada.

bames53
fuente
14
Esto es 5 años demasiado tarde, así que no voy a publicarlo como una respuesta y no aceptaré esta, pero para cualquiera que todavía esté confundido por la terminología incluso después de leer esto: streambufes para datos sin procesar (por ejemplo, bytes sin procesar, entradas sin , etc.), mientras que streames para datos preparados (texto, enteros formateados como texto, etc.). Dicho de otra manera, streamrepresenta la capa de análisis (o serialización). Cuando se trata de cadenas simples, técnicamente puede usar cualquiera de las dos, pero el significado es diferente: streambufsignifica que desea que los datos sin procesar sean la cadena en sí, mientras que streamabstrae la codificación.
user541686
@Mehrdad ¿Puedo preguntar qué significa decir que se streamabstrae la codificación ? : D ¿Puede explicarlo un poco más o proporcionar más material?
Rick
3
@Rick: Claro. streames responsable de leer y escribir objetos en a streambuf. streambufes responsable de guardar y restaurar bytes (o caracteres / palabras / como prefiera llamarlos) desde una ubicación de almacenamiento de bytes. El mapeo entre objetos y bytes es a lo que me refería como "codificación". Un ejemplo de esto es que a streamaceptaría un inty luego decidiría cómo convertirlo en chars, y viceversa; podría usar el formato big-endian, el formato little-endian, un formato invertido de bits, un formato de 7 bits solo formato, o cualquier otra cosa. es decir, abstrae el formato de almacenamiento.
user541686
69

Con la ayuda de streambuf, podemos trabajar en un nivel aún más bajo . Permite el acceso a los búferes subyacentes.

Aquí hay algunos buenos ejemplos: Copie, cargue, redirija y tee usando streambufs C ++ y en referencia a la comparación, esto podría ser útil,

ingrese la descripción de la imagen aquí

Vea esto para más detalles: Biblioteca IOstream

COD3BOY
fuente
2
Busqué por todas partes algo que pudiera explicar tanto el streambuf como este artículo. ¡Gracias por ayudarme a encontrarlo!
wvdschel
1
El ejemplo siempre es mejor. Gracias
eigenfield