Using GIOChannel

http://www.symlab.org/main/documentation/reference/s3/pdk/GUID-817C43E8-9169-4750-818B-B431D138D71A.html


GIOChannel provides a portable method for using file descriptors,sockets and pipes and integrating them into the GLib main loop.

The g_io_channel_unix_new() API takes a file descriptoras an input parameter and is used to create a new GIOChannel.Alternatively, the g_io_channel_new_file() API can be usedto create a channel for a file. Once the channel is created, it can be usedin a generic manner.

To read a channel, APIs such as the following can be used:

  • g_io_channel_read_chars()

  • g_io_channel_read_line()

  • g_io_channel_read_to_end()

To write to a channel an API like g_io_channel_write_chars() isused.

To set the position in the current GIOChannel, g_io_channel_seek_position() canbe used.

Finally the channel can be closed using g_io_channel_shutdown().

The following is an example code where a file descriptor to a plain fileis used to create a GIOChannel, and then the contents ofthe file are read in chunks of 100 bytes and printed using g_print.Finally the channel is closed.

#include <glib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
	GIOChannel *channel;
	gchar buf[100];
	gsize bytes_read;
	FILE *fp;
	
	if(argc != 2)
	{
		g_print("usage:cat <file_name>\n");
		g_print("Press any key to exit\n");
		getchar();
		return 1;
	}
	
	fp = fopen(argv[1],"r");
	
	if(!fp)
	{
		g_print("Unable to open the file %s\n",argv[1]);
		return 1;
	}
		
	channel = g_io_channel_unix_new(fileno(fp));
	
 	do
 	{
		g_io_channel_read_chars(channel,buf,100,&bytes_read,NULL);
		g_print("%s",buf);
		
	}
	while(bytes_read > 0);
	
	g_io_channel_shutdown(channel,TRUE,NULL);
	
	fclose(fp);
 
	return 0;
}
 

In the example below, a sample code to copy a file is written. In the code,channels are opened using g_io_channel_new_file(). The contentsof the file are read using g_io_channel_read_chars(), andthe contents are written to a new file using g_io_channel_write_chars().

#include <glib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
	GIOChannel *in_channel,*out_channel;
	gchar buf[100];
	gsize bytes_read,bytes_written;
	GError *error = NULL;
	
	if(argc != 3)
	{
		g_print("usage:<cp SOURCE> <DESTINATION>\n");
		g_print("Press any key to exit\n");
		getchar();
		return 1;
	}
		
	in_channel = g_io_channel_new_file(argv[1],"r",&error);
	
	if(!in_channel)
	{
		g_print("Unable to open the file %s to read\n",argv[1]);
		g_print("Press any key to exit\n");
		getchar();
		return 1;
	}
	
	out_channel = g_io_channel_new_file(argv[2],"w",&error);
	
	if(!out_channel)
	{
		g_print("Unable to open the file %s to write\n",argv[2]);
		g_print("Press any key to exit\n");
		getchar();
		return 1;
	}
	
	do
	{
		g_io_channel_read_chars(in_channel,buf,100,&bytes_read,&error);
		if(error)
		{
			g_print("Error while reading file %s\n",argv[1]);
			g_print("Press any key to exit\n");
			getchar();
			return 1;
		}
		
		g_io_channel_write_chars(out_channel,buf,bytes_read,&bytes_written,&error);
		if(error)
		{
			g_print("Error while writing file %s\n",argv[2]);
			g_print("Press any key to exit\n");
			getchar();
			return 1;
		}
	}
	while(bytes_read > 0);
	
       g_io_channel_shutdown(in_channel,TRUE,&error);
	if(error)
	{
		g_print("Error has occured\n");
		g_print("Press any key to exit\n");
		getchar();
		return 1;
	}
	 
	g_io_channel_shutdown(out_channel,TRUE,&error);
 	if(error)
	{
		g_print("Error has occured\n");
		g_print("Press any key to exit\n");
		getchar();
		return 1;
	}
	
	g_print("File copied successfully...\n");
	getchar();
	
	return 0;
}

Using GIOChannel inGLib main loops

GIOChannel provides a wayto integrate file descriptors to main loops. The following code demonstratesthe usage. In the code, a pipe is created. A thread is created which writesto the write end of the pipe. The main loop checks if the other end of thepipe is ready to read. If it is, then the callback function is called. Thecallback calls g_main_loop_quit(), and the main loop is terminatedand g_main_loop_run() returns.

#include <glib.h>
#include <stdio.h>

int fd[2];

void *thread_function(void *data)
{
	// call sleep so that the main loop source is not ready immediately
	sleep(10);
	
	write(fd[1],"GIOChannel main loop example",29);
	return NULL;
}

gboolean my_callback(GIOChannel *source,GIOCondition condition,gpointer data)
{
	char buf[100];	
	
	read(fd[0],buf,sizeof(buf));
	g_print("%s",buf);
	
	getchar();
	
	g_main_loop_quit((GMainLoop *)data);
	
	return FALSE;
}

int main()
{
	GMainLoop *loop;
	GIOChannel *channel;
	
	pipe(fd);
	
	channel = g_io_channel_unix_new(fd[0]);
	
	g_thread_init(NULL);
	g_thread_create(thread_function,NULL,TRUE,NULL);
	
	loop = g_main_loop_new(NULL,FALSE);
	g_io_add_watch(channel,G_IO_IN | G_IO_HUP | G_IO_ERR,(GIOFunc)my_callback,loop);
	g_main_loop_run(loop);
	
	g_io_channel_shutdown(channel,TRUE,NULL);

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值