Using GIOChannel (如何使用giochannel)

本文介绍了GIOChannel在GLib中的应用,包括如何使用GIOChannel进行文件读写、复制及集成到GLib主循环中。并通过示例代码展示了具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于usbip相关代码使用了giochannel,该部分功能包含于glib中,所以找到此文以做翻译。


Using GIOChannel


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

GIOChannel提供一种很方便的可以用于文件描述符,套接字和管道并且将他们集成到glib的主循环的方法。

The g_io_channel_unix_new() API takes a file descriptor as an input parameter and is used to create a new GIOChannel

g_io_channel_unix_new() API 将一个文件描述符作为输入参数并且用其产生一个新的GIOChannel。

Alternatively, the g_io_channel_new_file() API can be used to create a channel for a file. Once the channel is created, it can be used in a generic manner.

另外,g_io_channel_new_file() API用于为一个文件创造一个io通道(相比较上面是为文件描述符创造io通道)。一旦通道建立,它就可以被用于常规的方式。

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

下面的API可以被用于读取一个通道:

  • 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() is used.

像是g_io_channel_write_chars这样的API可以被用于向一个通道中写入数据。

To set the position in the current GIOChannelg_io_channel_seek_position() can be used.

若是想在当前的GIOChannel中设置位置,那么g_io_channel_seek_position()会被用到。

Finally the channel can be closed using g_io_channel_shutdown().

最后通道可以使用g_io_channel_shutdown()关闭。

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

如下是一个示例代码,代码描述了使用一个普通文件的文件描述符创建一个GIOChannel,然后改文件的内容被按照100byte每块的方式读取并且使用g_print打印出来,最后该通道被关闭。

#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 contents of the file are read using g_io_channel_read_chars(), and the contents are written to a new file using g_io_channel_write_chars().

在如下的示例中,代码被用于拷贝一个文件。在如下代码中,通道使用g_io_channel_new_file API打开文件。文件的内容使用g_io_channel_read_chars API读取数据,文件内容使用g_io_channel_write_chars API写入到一个新文件中去

#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 in GLib main loops

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

GIOChannel 提供一个方法去集成文件描述符到主循环当中(main loops)。如下代码演示使用方法。在如下代码中,管道被创建,一个线程被创建并且向管道末端写入数据。主循环检查其他管道末端是否准备好去读取。如果条件满足,回调函数就会被调用。回调函数调用g_main_loop_quit,并且主循环终止于g_main_loop_run函数的返回。

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值