嵌入式Linux应用程序开发(第二版文件I/O编程)

嵌入式Linux应用程序开发(第二版文件I/O编程)嵌入式Linux应用程序开发(第二版文件I/O编程)_第1张图片

1.例题:基本功能:从源文件复制到目标文件

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>

#define BUFFER_SIZE 1024     /*每次读写缓存大小为1KB,大小不同,运行效率不同*/
#define SRC_FILE_NAME "src_file"     /*源文件名,建议使用宏定义*/
#define DEST_FILE_NAME "dest_file"   //目标文件名*/
#define OFFSET 10240       //复制的数据大小,这里为10KB*/

int main()
{
	int src_file,dest_file;        /*文件描述符*/
	unsigned char buff[BUFFER_SIZE];     /*定义用于缓冲数据的数组*/
	int real_read_len;     /*read()函数实际读取到的字节*/
	
	 /*以只读方式打开源文件*/
	src_file = open(SRC_FILE_NAME, O_RDONLY);
	 /* 以只写方式打开目标文件,若此文件不存在则创建该文件,访问权限为644*/
	dest_file = open(DEST_FILE_NAME,O_WRONLY|O_CREAT,0644);
	 /*如果打开文件出错,则退出程序*/
	if(src_file < 0 || dest_file < 0)
	{
		printf("Open file error\n");
		exit(1);
	}
	/* 将源文件的读/写指针移到下标为0的起始位置*/
	lseek(src_file, 0, SEEK_SET);   //复制所有
	 /* 读取源文件的最后2KB数据并写到目标文件中,每次读写1KB*/
	while((real_read_len = read(src_file, buff ,sizeof(buff))) > 0)
	{
		write(dest_file, buff, real_read_len);
	}
	 /* 关闭文件,释放资源*/
	close(dest_file);
	close(src_file);
	return 0;
}

#:gcc copy_file.c -o copy_file
#:./copy_file
#:ls lh dest_file
-rw-r–r-- 1

2.文件锁

2.1文件记录锁功能原码

/*lock_set.c*/
int lock_set(int fd,int type)
{
	struct flock old_lock,lock;  /*定义flock结构体*/
	lock.l_whence=SEEK_SET;  /*加锁整个文件*/
	lock.l_start=0;
	lock.l_len=0;  
	lock.l_type=type;   
	lock.l_pid=-1;    
	/*判断文件是否可以上锁 */
	fcntl(fd,F_GETLK,&lock);
	if(lock.l_type!=F_UNLCK)
	{
		 /*判断文件不能上锁的原因 */
		if(lock.l_type==F_RDLCK) /*该文件已经有读取锁 */
		{
   			printf("Read lock already set by %d\n",lock.l_pid);
 		} 
 		else if(lock.l_type==F_WRLCK) /*该文件已经有写入锁 */
 		{
   			printf("Write lock already set by %d\n",lock.l_pid);     
 		}
	}

	/*l_type 可能在执行完上述判断后被修改了*/
	lock.l_type=type;
	/*根据不同的type值进行阻塞式上锁或解锁*/
	if((fcntl(fd,F_SETLKW,&lock))<0)
	{
		printf("Lock failed:type=%d\n",lock.l_type);
 		return 1; 
	}
	switch(lock.l_type)
	{
		case F_RDLCK:
		{
			printf("Read lock set by %d\n",getpid());/*getpid()用来得到当前的进程号*/ 
		} 
		break;
		case F_WRLCK:
		{
			printf("Write lock set by %d\n",getpid());
		} 
		break;
		case F_UNLCK:
		{
			printf("Release lock set by %d\n",getpid());
			return 1;
		} 
		break;
		default:break;      
	}  /*end of switch*/
	return 0;
} 

2.2写入锁的测试用例

首先自己创建一个hello文件
之后对其上写入锁
最后释放写入锁
代码如下:

/*write_lock.c*/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/file.h>
#include"lock_set.c"

int main(void)
{	
	int fd;
	/*首先打开文件*/
	fd=open("/home/text/3-30/hello",O_RDWR|O_CREAT,0644); //绝对路径和相对路径都可以 
	if(fd<0)
	{
		printf("Open file error!\n");
		exit(1); 
	}
 
	/*给文件上写入锁*/
	lock_set(fd,F_WRLCK);
	getchar();  /*当用户输入任意键后,程序继续执行,否则等待*/
	
	/*给文件解锁*/
	lock_set(fd,F_UNLCK);
	getchar();
	close(fd);  /*关闭该文件*/
	exit(0);
}

为了更好的验证写入锁是排斥锁
那咱们可以同时打开两个终端,先运行一个./write_lock ,同时去另一个终端上运行./write_lock
第二个终端会提示:write lock already set by 4888
结论:写入锁为互斥锁,同一时刻只能有一个写入锁存在

2.3文件的读取锁的测试用例(原理同上)

/*read_lock.c*/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/file.h>
#include"lock_set.c"

int main(void)
{
	int fd;
 
	/*首先打开文件*/
	fd=open("hello",O_RDWR|O_CREAT,0644);
	if(fd<0)
	{
		printf("Open file error!\n");
		exit(1); 
	}
	 /*给文件上读取锁*/
	lock_set(fd,F_RDLCK);
	getchar();  /*当用户输入任意键后,程序继续执行,否则等待*/
	/*给文件解锁*/
	lock_set(fd,F_UNLCK);
	getchar();  /*当用户输入任意键后,程序继续执行,否则等待*/  
	close(fd);  /*关闭该文件,释放锁*/
	exit(0); 

}

为了验证写锁为共享锁,咱们也要去打开两个终端,分别去运行./read_lock
。两个终端都能够成功运行,并且获得不同的PID(进程号)
结论:读锁为共享锁,同一时刻可以多可用户读取

2.4猜想:读锁与写锁之间有没有关系

1.当在一个终端上运行读锁的,另一个终端上能运行写入锁吗?结果会怎样?
嵌入式Linux应用程序开发(第二版文件I/O编程)_第2张图片

2.5娱乐社区(可忽略)

点赞 点赞 点赞
嵌入式Linux应用程序开发(第二版文件I/O编程)_第3张图片

嵌入式Linux应用程序开发(第二版文件I/O编程)_第4张图片

你可能感兴趣的:(Linux实训,linux)