Differences between revisions 7 and 8
Revision 7 as of 2008-01-02 21:23:11
Size: 17426
Comment:
Revision 8 as of 2008-12-04 08:49:13
Size: 17475
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
[[TableOfContents()]] <<TableOfContents>>
Line 13: Line 13:
Para crear un `GIOChannel`, primero se debe crear el descriptor de archivo de UNIX por los métodos convencionales (open, socket, etc.) y luego utilizar ''[#g_io_channel_unix_new g_io_channel_unix_new]'' o bien ''[#g_io_channel_new_file g_io_channel_new_file]'' para acceder a archivos directamente.

[[Anchor(g_io_channel_unix_new)]]
Para crear un `GIOChannel`, primero se debe crear el descriptor de archivo de UNIX por los métodos convencionales (open, socket, etc.) y luego utilizar ''[[#g_io_channel_unix_new|g_io_channel_unix_new]]'' o bien ''[[#g_io_channel_new_file|g_io_channel_new_file]]'' para acceder a archivos directamente.

<<Anchor(g_io_channel_unix_new)>>
Line 22: Line 22:
[[Anchor(g_io_channel_new_file)]] <<Anchor(g_io_channel_new_file)>>
Line 62: Line 62:
Los canales tienen un tiempo de vida controlado por conteo de referencias. Inicialmente, los canales se crean con una cuenta de 1 y, cuando la misma cae a 0, se destruyen. Para obtener una referencia se utiliza la función ''[#g_io_channel_ref g_io_channel_ref]'' y para liberar una referencia ''[#g_io_channel_unref g_io_channel_unref]''. Cabe aclarar que, aunque el objeto `GIOChannel` se destruya, no necesariamente se cierra el canal. En concreto, si el objeto fue creado a partir de un descriptor de UNIX, el programador es responsable de cerrarlo (a menos que se utilice la función ''g_io_channel_set_close_on_unref''. Los canales tienen un tiempo de vida controlado por conteo de referencias. Inicialmente, los canales se crean con una cuenta de 1 y, cuando la misma cae a 0, se destruyen. Para obtener una referencia se utiliza la función ''[[#g_io_channel_ref|g_io_channel_ref]]'' y para liberar una referencia ''[[#g_io_channel_unref|g_io_channel_unref]]''. Cabe aclarar que, aunque el objeto `GIOChannel` se destruya, no necesariamente se cierra el canal. En concreto, si el objeto fue creado a partir de un descriptor de UNIX, el programador es responsable de cerrarlo (a menos que se utilice la función ''g_io_channel_set_close_on_unref''.
Line 66: Line 66:
[[Anchor(g_io_channel_ref)]] <<Anchor(g_io_channel_ref)>>
Line 71: Line 71:
[[Anchor(g_io_channel_unref)]] <<Anchor(g_io_channel_unref)>>
Line 78: Line 78:
[[Anchor(g_io_channel_shutdown)]] <<Anchor(g_io_channel_shutdown)>>
Line 90: Line 90:
Si el tipo de canal lo permite, la función ''[#g_io_channel_seek_position g_io_channel_seek_position]'' sirve para establecer la siguiente posición donde se leerá o escribirá. Normalmente sólo los archivos permiten posicionamiento aleatorio.

[[Anchor(g_io_channel_seek_position)]]
Si el tipo de canal lo permite, la función ''[[#g_io_channel_seek_position|g_io_channel_seek_position]]'' sirve para establecer la siguiente posición donde se leerá o escribirá. Normalmente sólo los archivos permiten posicionamiento aleatorio.

<<Anchor(g_io_channel_seek_position)>>
Line 106: Line 106:
[[Anchor(g_io_channel_read_chars)]] <<Anchor(g_io_channel_read_chars)>>
Line 113: Line 113:
Lee una cantidad máxima (`tamaño_buffer`) de bytes del canal como caracteres y los almacena en `buffer`. Éste debe estar previamente reservado (p.e. con ''[#g_malloc g_malloc]''). `bytes_leidos` contiene la cantidad de bytes efectivamente leídos (puede ser menor que la solicitada). Lee una cantidad máxima (`tamaño_buffer`) de bytes del canal como caracteres y los almacena en `buffer`. Éste debe estar previamente reservado (p.e. con ''[[#g_malloc|g_malloc]]''). `bytes_leidos` contiene la cantidad de bytes efectivamente leídos (puede ser menor que la solicitada).
Line 117: Line 117:
[[Anchor(g_io_channel_read_line)]] <<Anchor(g_io_channel_read_line)>>
Line 124: Line 124:
Lee una línea completa del canal y almacena el puntero a la misma en `puntero_cadena`. Una vez finalizada la operación con la línea, es responsabilidad del programador liberar la memoria con ''[#g_free g_free]''. En `bytes_leidos` se devuelve la cantidad total de bytes leídos (incluyendo caracteres de fin de línea) y en terminador, sólo la cantidad perteneciente a la línea en sí. Tanto `bytes_leidos` como `terminador` pueden ser nulos si la información no es de interés.

[[Anchor(g_io_channel_read_line_string)]]
Lee una línea completa del canal y almacena el puntero a la misma en `puntero_cadena`. Una vez finalizada la operación con la línea, es responsabilidad del programador liberar la memoria con ''[[#g_free|g_free]]''. En `bytes_leidos` se devuelve la cantidad total de bytes leídos (incluyendo caracteres de fin de línea) y en terminador, sólo la cantidad perteneciente a la línea en sí. Tanto `bytes_leidos` como `terminador` pueden ser nulos si la información no es de interés.

<<Anchor(g_io_channel_read_line_string)>>
Line 132: Line 132:
Similar a ''[#g_io_channel_read_line g_io_channel_read_line]'', sólo que, para devolver el resultado, utiliza una estructura GString. `terminador` puede ser nulo.

[[Anchor(g_io_channel_read_to_end)]]
Similar a ''[[#g_io_channel_read_line|g_io_channel_read_line]]'', sólo que, para devolver el resultado, utiliza una estructura GString. `terminador` puede ser nulo.

<<Anchor(g_io_channel_read_to_end)>>
Line 140: Line 140:
Lee todos los bytes disponibles en el canal hasta encontrar el fin de archivo. En `puntero_cadena` se devuelve un puntero al espacio de memoria asignado a tal fin que luego debe ser liberado con ''[#g_free g_free]''.

Para la escritura se utiliza la contra parte de ''[#g_io_channel_read_chars g_io_channel_read_chars]'':

[[Anchor(g_io_channel_write_chars)]]
Lee todos los bytes disponibles en el canal hasta encontrar el fin de archivo. En `puntero_cadena` se devuelve un puntero al espacio de memoria asignado a tal fin que luego debe ser liberado con ''[[#g_free|g_free]]''.

Para la escritura se utiliza la contra parte de ''[[#g_io_channel_read_chars|g_io_channel_read_chars]]'':

<<Anchor(g_io_channel_write_chars)>>
Line 153: Line 153:
Se aplican las mismas restricciones en cuanto a codificación del canal que para ''[#g_io_channel_read_chars g_io_channel_read_chars]''. Se aplican las mismas restricciones en cuanto a codificación del canal que para ''[[#g_io_channel_read_chars|g_io_channel_read_chars]]''.
Line 168: Line 168:
La forma básica de integrar un objeto generador de eventos al bucle es obtener una estructura `GSource`. En el caso de los canales, la función para ello es ''[#g_io_create_watch g_io_create_watch]'':

[[Anchor(g_io_create_watch)]]
La forma básica de integrar un objeto generador de eventos al bucle es obtener una estructura `GSource`. En el caso de los canales, la función para ello es ''[[#g_io_create_watch|g_io_create_watch]]'':

<<Anchor(g_io_create_watch)>>
Line 175: Line 175:
Esta función devuelve un `GSource` que luego se registra en algún bucle de eventos con ''[#g_source_attach g_source_attach]''. Sin embargo, por conveniencia, GLib provee un par adicional de funciones para integrar directamente un canal al bucle principal: ''[#g_io_watch g_io_watch]'' y ''[#g_io_add_watch_full g_io_add_watch_full]''.

[[Anchor(g_io_add_watch)]]
Esta función devuelve un `GSource` que luego se registra en algún bucle de eventos con ''[[#g_source_attach|g_source_attach]]''. Sin embargo, por conveniencia, GLib provee un par adicional de funciones para integrar directamente un canal al bucle principal: ''[[#g_io_watch|g_io_watch]]'' y ''[[#g_io_add_watch_full|g_io_add_watch_full]]''.

<<Anchor(g_io_add_watch)>>
Line 203: Line 203:
Las funciones para manipular la codificación son ''[#g_io_channel_set_encoding g_io_channel_set_encoding]'' y ''[#g_io_channel_get_encoding g_io_channel_get_encoding]''.

[[Anchor(g_io_channel_set_encoding)]]
Las funciones para manipular la codificación son ''[[#g_io_channel_set_encoding|g_io_channel_set_encoding]]'' y ''[[#g_io_channel_get_encoding|g_io_channel_get_encoding]]''.

<<Anchor(g_io_channel_set_encoding)>>
Line 211: Line 211:
[[Anchor(g_io_channel_get_encoding)]] <<Anchor(g_io_channel_get_encoding)>>
Line 220: Line 220:
 * El canal es sobre un archivo y el puntero de lectura y escritura acaba de ser colocado con ''[#g_io_channel_seek_position g_io_channel_seek_position]''.  * El canal es sobre un archivo y el puntero de lectura y escritura acaba de ser colocado con ''[[#g_io_channel_seek_position|g_io_channel_seek_position]]''.
Line 222: Line 222:
 * Se ha llamado a una función de lectura y ha devuelto `G_IO_STATUS_EOF` o, en el caso de ''[#g_io_channel_read_to_end g_io_channel_read_to_end]'', `G_IO_STATUS_NORMAL`.  * Se ha llamado a una función de lectura y ha devuelto `G_IO_STATUS_EOF` o, en el caso de ''[[#g_io_channel_read_to_end|g_io_channel_read_to_end]]'', `G_IO_STATUS_NORMAL`.
Line 230: Line 230:
[[Anchor(g_io_channel_set_line_term)]] <<Anchor(g_io_channel_set_line_term)>>
Line 236: Line 236:
[[Anchor(g_io_channel_get_line_term)]] <<Anchor(g_io_channel_get_line_term)>>
Line 244: Line 244:
La API de GIOChannel permite modificar alguno de los parámetros de funcionamiento interno del canal. Es posible modificar el tamaño del buffer interno del mismo para optimizar el rendimiento de lectura y escritura en casos especiales. Para ello se utilizan las funciones ''[#g_io_channel_get_buffer_size g_io_channel_get_buffer_size]'' y ''[#g_io_channel_set_buffer_size g_io_channel_set_buffer_size]''.

[[Anchor(g_io_channel_get_buffer_size)]]
La API de GIOChannel permite modificar alguno de los parámetros de funcionamiento interno del canal. Es posible modificar el tamaño del buffer interno del mismo para optimizar el rendimiento de lectura y escritura en casos especiales. Para ello se utilizan las funciones ''[[#g_io_channel_get_buffer_size|g_io_channel_get_buffer_size]]'' y ''[[#g_io_channel_set_buffer_size|g_io_channel_set_buffer_size]]''.

<<Anchor(g_io_channel_get_buffer_size)>>
Line 251: Line 251:
[[Anchor(g_io_channel_set_buffer_size)]] <<Anchor(g_io_channel_set_buffer_size)>>
Line 256: Line 256:
Si en ''[#g_io_channel_set_buffer_size g_io_channel_set_buffer_size]'' se especifica un tamaño 0, GLib elegirá un tamaño adecuado al canal.

Se ha visto antes que, utilizando el bucle de eventos, se puede supervisar un canal y producir llamadas a funciones ante determinados eventos. También es posible verificar manualmente si un canal tiene datos listos para la lectura o si se pueden escribir datos en él. Para ello se utiliza la función ''[#g_io_channel_get_buffer_condition g_io_channel_get_buffer_condition]''.

[[Anchor(g_io_channel_get_buffer_condition)]]
Si en ''[[#g_io_channel_set_buffer_size|g_io_channel_set_buffer_size]]'' se especifica un tamaño 0, GLib elegirá un tamaño adecuado al canal.

Se ha visto antes que, utilizando el bucle de eventos, se puede supervisar un canal y producir llamadas a funciones ante determinados eventos. También es posible verificar manualmente si un canal tiene datos listos para la lectura o si se pueden escribir datos en él. Para ello se utiliza la función ''[[#g_io_channel_get_buffer_condition|g_io_channel_get_buffer_condition]]''.

<<Anchor(g_io_channel_get_buffer_condition)>>
Line 269: Line 269:
[[Anchor(g_io_channel_get_flags)]] <<Anchor(g_io_channel_get_flags)>>
Line 274: Line 274:
[[Anchor(g_io_channel_set_flags)]] <<Anchor(g_io_channel_set_flags)>>
Line 280: Line 280:
Los valores que puede tomar el parámetro banderas son `G_IO_FLAG_APPEND` y/o `G_IO_FLAG_NONBLOCK` (los demás valores son de sólo lectura). El valor obtenido en ''[#g_io_channel_get_flags g_io_channel_get_flags]'' es una composición de: Los valores que puede tomar el parámetro banderas son `G_IO_FLAG_APPEND` y/o `G_IO_FLAG_NONBLOCK` (los demás valores son de sólo lectura). El valor obtenido en ''[[#g_io_channel_get_flags|g_io_channel_get_flags]]'' es una composición de:
Line 286: Line 286:
 * `G_IO_FLAG_IS_SEEKABLE`: se puede mover el puntero en el canal mediante la utilización de ''[#g_io_channel_seek_position g_io_channel_seek_position]''.  * `G_IO_FLAG_IS_SEEKABLE`: se puede mover el puntero en el canal mediante la utilización de ''[[#g_io_channel_seek_position|g_io_channel_seek_position]]''.
Line 289: Line 289:
'''''Volver a:''''' [:Documentacion/Desarrollo/Glib:GLib] '''''Volver a:''''' [[Documentacion/Desarrollo/Glib|GLib]]

Tratamiento de archivos y canales de entrada/salida

Para el tratamiento de archivos y canales de entrada/salida en general, GLib provee un tipo de dato llamado GIOChannel, que permite encapsular archivos, sockets y tuberías. Esta abstracción no sólo posibilita el acceso uniforme a todos estos recursos, sino que también asegura portabilidad e integración al bucle de eventos.

Actualmente sólo hay soporte completo para UNIX, aunque el tratamiento con archivos puede hacerse independientemente de la plataforma.

Obtención de un GIOChannel.

Para crear un GIOChannel, primero se debe crear el descriptor de archivo de UNIX por los métodos convencionales (open, socket, etc.) y luego utilizar g_io_channel_unix_new o bien g_io_channel_new_file para acceder a archivos directamente.

GIOChannel *g_io_channel_unix_new(int fd);

Esta función devuelve el canal creado a partir del descriptor. Dicho parámetro se puede recuperar después utilizando la función g_io_channel_unix_get_fd.

GIOChannel *g_io_channel_new_file(const gchar *nombre_archivo,
                                  const gchar *modo, GError **error);

Devuelve un nuevo canal para acceder al archivo nombre_archivo. El modo tiene la misma forma que el parámetro modo de la función de C estándar fopen. Esto es:

  • r para lectura.

  • r+ para lectura y escritura.

  • w para escritura (Si el archivo no existe, lo crea; en caso contrario lo trunca).

  • w+ para lectura y escritura (con el archivo hace lo mismo que el parámetro w

  • a para escritura al final del archivo (lo crea si no existe).

  • a+ para lectura y escritura al final del archivo (lo crea si no existe).

El parámetro error debe apuntar a una estructura tipo GError previamente creada y es aquí donde se informa de cualquier problema al abrir el archivo. En este último caso la función retorna NULL.

Generalidades en el trabajo con GIOChannels.

Una vez obtenido el GIOChannel, en general, todas las llamadas a funciones para realizar alguna operación sobre el canal (lectura, escritura, etc.) tomarán como primer parámetro al propio canal y como último un puntero, error, a una estructura GError, donde se informará de cualquier inconveniente ocurrido al intentar la operación. Además, la mayoría de las funciones retornan un código del tipo GIOStatus que puede tomar los siguientes valores:

  • GIO_STATUS_ERROR: ocurrió un error (los detalles del mismo se encuentran en el parámetro error).

  • G_IO_STATUS_NORMAL: la operación se realizó con éxito.

  • G_IO_STATUS_EOF: se alcanzó el fin de archivo.

  • G_IO_STATUS_AGAIN: el recurso solicitado no está disponible (p.e., se intentó leer datos, pero no estaban en ese momento).

En caso de que el código de retorno sea G_IO_STATUS_ERROR, en la estructura GError se almacena otro código, indicando con mayor detalle la naturaleza del problema. Este nuevo código es de tipo GIOChannelError y puede tomar los siguientes valores:

  • G_IO_CHANNEL_ERROR_FBIG: el archivo es muy grande.

  • G_IO_CHANNEL_ERROR_INVAL: argumento inválido.

  • G_IO_CHANNEL_ERROR_IO: error general de entrada/salida.

  • G_IO_CHANNEL_ISDIR: el archivo es un directorio, pero se intentó acceder a él como un archivo regular.

  • G_IO_CHANNEL_ERROR_NOSPC: No hay más espacio disponible para escritura.

  • G_IO_CHANNEL_ERROR_NXIO: No existe tal dispositivo o dirección.

  • G_IO_CHANNEL_ERROR_OVERFLOW: el valor proporcionado es mayor de lo que permite su tipo.

  • G_IO_CHANNEL_ERROR_PIPE: algunos de los extremos de la tubería lo desconectó.

  • G_IO_CHANNEL_ERROR_FAILED: otros errores.

Los primeros valores tienen su correspondencia directa con los valores de la variable errno estándar de C. El último se reserva para otra clase de errores no identificados.

Los canales tienen un tiempo de vida controlado por conteo de referencias. Inicialmente, los canales se crean con una cuenta de 1 y, cuando la misma cae a 0, se destruyen. Para obtener una referencia se utiliza la función g_io_channel_ref y para liberar una referencia g_io_channel_unref. Cabe aclarar que, aunque el objeto GIOChannel se destruya, no necesariamente se cierra el canal. En concreto, si el objeto fue creado a partir de un descriptor de UNIX, el programador es responsable de cerrarlo (a menos que se utilice la función g_io_channel_set_close_on_unref.

Las funciones mencionadas tienen la siguiente forma:

void g_io_channel_ref(GIOChannel *canal);

void g_io_channel_unref(GIOChannel *canal);

Para cerrar de un canal se utiliza g_io_channel_shutdown:

GIOStatus g_io_channel_shutdown(GIOChannel *canal, gboolean descarga,
                                GError **error);

Aquí, el parámetro descarga controla si se escriben los datos que pueda haber en el buffer interno del canal antes de cerrarlo (para forzar una descarga en cualquier momento se puede utilizar g_io_channel_flush.

Operaciones básicas.

GLib provee una serie de funciones para acceder a un canal abierto de diversas maneras: por caracteres individuales, por bloques de cantidad de bytes fijos y por líneas.

Si el tipo de canal lo permite, la función g_io_channel_seek_position sirve para establecer la siguiente posición donde se leerá o escribirá. Normalmente sólo los archivos permiten posicionamiento aleatorio.

GIOStatus g_io_channel_seek_position(GIOChannel *canal, glong posicion,
                                     GSeekType tipo_posicion, GError **error);

La semántica de posicion (que es un número con signo) queda determinada por el tipo_posicion, que puede tomar los siguientes valores:

  • G_SEEK_CUR: la nueva posición es relativa a la actual.

  • G_SEEK_SET: la nueva posición se toma a partir del principio del archivo.

  • G_SEEK_END: la nueva posición es absoluta respecto al fin de archivo.

Para efectuar lecturas en un canal se utilizan algunas de las siguientes funciones:

GIOStatus g_io_channel_read_chars(GIOChannel *canal, gchar *buffer,
                                  gsize tamaño_buffer, gsize *bytes_leidos,
                                  GError **error);

Lee una cantidad máxima (tamaño_buffer) de bytes del canal como caracteres y los almacena en buffer. Éste debe estar previamente reservado (p.e. con g_malloc). bytes_leidos contiene la cantidad de bytes efectivamente leídos (puede ser menor que la solicitada).

Es importante notar que si el canal está configurado para trabajar con caracteres Unicode, un carácter puede ocupar más de un byte y, si el buffer no es lo suficientemente grande, puede que no sea posible almacenar ningún carácter. En estas condiciones bytes_leidos es cero, pero no hay indicación de error.

GIOStatus g_io_channel_read_line(GIOChannel *canal, gchar **puntero_cadena,
                                 gsize *bytes_leidos, gsize *terminador,
                                 GError **error);

Lee una línea completa del canal y almacena el puntero a la misma en puntero_cadena. Una vez finalizada la operación con la línea, es responsabilidad del programador liberar la memoria con g_free. En bytes_leidos se devuelve la cantidad total de bytes leídos (incluyendo caracteres de fin de línea) y en terminador, sólo la cantidad perteneciente a la línea en sí. Tanto bytes_leidos como terminador pueden ser nulos si la información no es de interés.

GIOStatus g_io_channel_read_line_string(GIOChannel *canal, GString *cadena,
                                        gsize *terminador, GError **error);

Similar a g_io_channel_read_line, sólo que, para devolver el resultado, utiliza una estructura GString. terminador puede ser nulo.

GIOStatus g_io_channel_read_to_end(GIOChannel *canal, gchar **puntero_cadena,
                                   gsize *bytes_leidos, GError **error);

Lee todos los bytes disponibles en el canal hasta encontrar el fin de archivo. En puntero_cadena se devuelve un puntero al espacio de memoria asignado a tal fin que luego debe ser liberado con g_free.

Para la escritura se utiliza la contra parte de g_io_channel_read_chars:

GIOStatus g_io_channel_write_chars(GIOChannel *canal, gchar *buffer,
                                   gsize cantidad_bytes, gsize *bytes_escritos,
                                   GError **error);

Como su propio nombre indica, esta función escribe en el canal cantidad_bytes del buffer. Puede que no lleguen a escribirse todos los bytes que se solicitaron, por lo que la función devuelve la cantidad de bytes efectivamente escritos. Si cantidad_bytes es -1 se considera al buffer como terminado en nulo.

Se aplican las mismas restricciones en cuanto a codificación del canal que para g_io_channel_read_chars.

Integración de canales al bucle de eventos.

Uno de los aspectos más interesantes de los GIOChannels es que es posible integrarlos fácilmente al bucle de eventos y así, por ejemplo, hacer que la aplicación reaccione ante la llegada de datos.

Los posibles tipos de eventos que puede generar un canal están dados por el tipo GIOCondition que toma los siguientes valores:

  • G_IO_IN: hay datos disponibles en el canal.

  • G_IO_OUT: se pueden escribir datos al canal sin que éste bloquee.

  • G_IO_PRI: hay datos urgentes para leer.

  • G_IO_ERR: condición de error.

  • G_IO_HUP: desconexión; normalmente, se aplica a sockets y tuberías. Alguno de los extremos rompió la conexión.

  • G_IO_NVAL: solicitud no válida (p.e. el descriptor UNIX no está abierto).

La forma básica de integrar un objeto generador de eventos al bucle es obtener una estructura GSource. En el caso de los canales, la función para ello es g_io_create_watch:

GSource *g_io_create_watch(GIOChannel *canal, GIOCondition condición);

Esta función devuelve un GSource que luego se registra en algún bucle de eventos con g_source_attach. Sin embargo, por conveniencia, GLib provee un par adicional de funciones para integrar directamente un canal al bucle principal: g_io_watch y g_io_add_watch_full.

guint g_io_add_watch(GIOChannel *canal, GIOCondition condición,
                     GIOFunc función, gpointer datos_usuario);

Esta función, que devuelve el identificador de evento, registra el canal para que sea controlado según las condiciones especificadas. En caso de que se cumpla alguna de las condiciones, se llama a la función con los datos_usuario adicionales.

La función especificada en el registro debe tener la siguiente forma:

gboolean (* GIOFunc)(GIOChannel *canal, GIOCondition condición,
                     gpointer datos_usuario);

La condición que la función recibe es aquella que causó el evento en primer lugar. datos_usario es lo que se especificó en el momento del registro.

La otra función, g_io_add_watch_full permite además especificar la prioridad del canal y una función de notificación cuando el canal se desconecta del bucle de eventos.

Configuración avanzada de canales.

Codificación

Los GIOChannels son capaces de codificar o decodificar los caracteres que se escriben o leen del mismo. La codificación que se utiliza internamente es UTF-8, por lo que, eventualmente, se puede transformar de UTF-8 a alguna otra codificación para escribir a un archivo, o viceversa.

Si se necesita que un canal no efectúe transformación alguna a los datos (por ejemplo, para tratamiento de datos binarios) se debe optar por la codificación nula (NULL).

Las funciones para manipular la codificación son g_io_channel_set_encoding y g_io_channel_get_encoding.

GIOStatus g_io_channel_set_encoding(GIOChannel *canal,
                                    const gchar *codificación, GError **error);

G_CONST_RETURN gchar *g_io_channel_get_encoding(GIOChannel *canal);

Por omisión, la codificación externa utilizada para archivos es UTF-8. Para cambiarla se deben tener en cuenta las siguientes condiciones:

  • El canal acaba de ser creado.
  • El canal es para escritura solamente.
  • El canal es sobre un archivo y el puntero de lectura y escritura acaba de ser colocado con g_io_channel_seek_position.

  • La codificación actual es UTF-8 o nula.
  • Se ha llamado a una función de lectura y ha devuelto G_IO_STATUS_EOF o, en el caso de g_io_channel_read_to_end, G_IO_STATUS_NORMAL.

Terminador de línea.

En UNIX, el fin de línea se indica con un carácter de linefeed (código ASCII 10), pero esto puede no ser cierto para otras plataformas (p.e. Win32).

Para que las funciones de lectura y escritura por líneas den los resultados esperados para cada plataforma, en caso de ser necesario el acceso a archivos escritos en otra plataforma, se debe configurar el terminador de línea en el canal. Las funciones para ello son:

void g_io_channel_set_line_term(GIOChannel *canal, const gchar *terminador,
                                gint longitud);

G_CONST_RETURN gchar *g_io_channel_get_line_term(GIOChannel *canal,
                                                 gint *longitud);

Configuración de buffer interno.

La API de GIOChannel permite modificar alguno de los parámetros de funcionamiento interno del canal. Es posible modificar el tamaño del buffer interno del mismo para optimizar el rendimiento de lectura y escritura en casos especiales. Para ello se utilizan las funciones g_io_channel_get_buffer_size y g_io_channel_set_buffer_size.

gsize g_io_channel_get_buffer_size(GIOChannel *canal);

void g_io_channel_set_buffer_size(GIOChannel *canal, gsize tamaño);

Si en g_io_channel_set_buffer_size se especifica un tamaño 0, GLib elegirá un tamaño adecuado al canal.

Se ha visto antes que, utilizando el bucle de eventos, se puede supervisar un canal y producir llamadas a funciones ante determinados eventos. También es posible verificar manualmente si un canal tiene datos listos para la lectura o si se pueden escribir datos en él. Para ello se utiliza la función g_io_channel_get_buffer_condition.

GIOCondition g_io_channel_get_buffer_condition(GIOChannel *canal);

Esta función puede devolver solamente G_IO_IN y G_IO_OUT y, por supuesto, su significado es exactamente el mismo que se explicó antes.

Por último, con las funciones [#g_io_channel_set_flags g_io_channel_set_flags] y [#g_io_channel_get_flags g_io_channel_get_flags], es posible saber y, en parte, modificar el comportamiento que tiene un canal.

GIOFlags g_io_channel_get_flags(GIOChannel *canal);

GIOStatus g_io_channel_set_flags(GIOChannel *canal, GIOFlags banderas,
                                 GError **error);

Los valores que puede tomar el parámetro banderas son G_IO_FLAG_APPEND y/o G_IO_FLAG_NONBLOCK (los demás valores son de sólo lectura). El valor obtenido en g_io_channel_get_flags es una composición de:

  • G_IO_FLAG_APPEND: canal en modo de agregado.

  • G_IO_FLAG_NONBLOCK: canal en modo no bloqueante; esto es, si se intenta, p.e., leer y no hay datos disponibles, se devuelve el control inmediatamente con un estado de G_IO_STATUS_AGAIN.

  • G_IO_FLAG_IS_READABLE: el canal se puede leer.

  • G_IO_FLAG_IS_WRITEABLE: se puede escribir en el canal.

  • G_IO_FLAG_IS_SEEKABLE: se puede mover el puntero en el canal mediante la utilización de g_io_channel_seek_position.


Volver a: GLib

Documentacion/Desarrollo/Glib/TratamientoDeficherosYCanalesDeEntradaYSalida (last edited 2008-12-04 08:49:13 by localhost)