Indice

Introduzione a Gio

Autore: Fabio Di Matteo
Ultima revisione: 30/05/2012

Gio è una libreria inclusa anche nel pacchetto gtk e il suo scopo è dotare Glib di uno strumento solido e multipiattaforma per I/O su file, flussi e socket. Fu scritta con lo scopo di rimpiazzare GnomeVFS e fornire un framework piu' comodo delle chiamate POSIX .

In questo articolo vedremo come copiare un file (una pagina web in questo caso) da una sorgente http al file system locale. Gio usa la logica degli uri per “raggiungere” i file, e sono molti i filesystem che supporta.

Il codice

main.c

#include <gio/gio.h>
 
 
int
main (int argc, char **argv)
{
	//Inizializzo i tipi di glib
	g_type_init();
 
	//Una varibile per gli eventuali errori
	GError *error;
 
	//Uri del Gfile sorgente(mySRC) e uri del Gfile di destinazione (myDEST)
	GFile*  mySRC =  g_file_new_for_uri("https://www.freemedialab.org/myip/index.php");
	GFile*  myDEST =  g_file_new_for_uri("file:///home/fabio/progetti/gio/myip.txt");
 
	//Copio il file con questa semplice funzione
	g_file_copy (mySRC,  myDEST,  G_FILE_COPY_OVERWRITE, NULL, NULL,  NULL,    &error);
 
 
	//Verifico se ci sono stati errori e stampo dei messaggi
	if (error!=NULL)
	{
		 g_error("Attenzione errore nella copia: %s\n",error->message);
	}else{
		 g_print("Copia eseguita correttamente.\n") ;
	} 
 
	return 0;
}

Come si puo' notare tutto il lavoro sporco lo fa la funzione g_file_copy().

Il makefile

makefile

CPP = gcc
OPTS = `pkg-config --cflags --libs gio-2.0` 

all:
	$(CPP)  main.c -o gio-test $(OPTS)

clean:
	rm gio-test

Tenere traccia dello stato di avanzamento delle operazioni

Puo' essere utile tenere traccia dei byte copiati mediante delle informazioni sullo schermo o perchè no anche una progressbar. Ecco come fare:

main.c

#include <gio/gio.h>
 
 
/* La funzione "progress" viene richiamata come callback dalla funzione "g_file_copy()"
 * e stampa a schermo le informazioni sull'avanzamento della copia.*/
 
GFileProgressCallback* 
progress(goffset current_num_bytes, goffset total_num_bytes, gpointer user_data)
{
	/* In "current_num_bytes" troviamo il numero di byte che si sta copiando  in questo momento;
	 * in "total_num_bytes" la dimesione del file;
	 * in "userdata" dati dell'utente (eventualmente) passati alla callback
	 * */
 
	g_print("Copia  in corso: %lld  di %lld byte\n", current_num_bytes, total_num_bytes );
}                                                         
 
 
 
int
main (int argc, char **argv)
{
	//Inizializzo i tipi di glib
	g_type_init();
 
	//Una varibile per gli eventuali errori
	GError *error;
 
	//Uri del Gfile sorgente(mySRC) e uri del Gfile di destinazione (myDEST)
	GFile*  mySRC =  g_file_new_for_uri("https://www.freemedialab.org/open50/bin/win32/open50.exe");
	GFile*  myDEST =  g_file_new_for_uri("file:///home/fabio/progetti/gio/open50.exe");
 
	/*Copio il file con questa semplice funzione. Il quinto parametro punta alla funzione progress
	 * responsabile delle informazioni sull'avanzamento dell' operazione*/
	g_file_copy (mySRC,  myDEST,  G_FILE_COPY_OVERWRITE, NULL, (GFileProgressCallback)progress,  NULL,    &error);
 
 
	//Verifico se ci sono stati errori e stampo dei messaggi
	if (error!=NULL)
	{
		 g_error("Attenzione errore nella copia: %s\n",error->message);
	}else{
		 g_print("Copia eseguita correttamente.\n") ;
	} 
 
	return 0;
}

Per compilare questo sorgente potremmo benissimo riusare il makefile usato per l'esempio base.