Linux —— 文件基本操作编程

任务一

使用Linux系统调用编写一个完成文件拷贝的C程序。

相关代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<dirent.h>
#define SIZE 1024	// 1024字节

/*文件是否存在*/
int is_Exist(char *file)
{
	if(access(file,F_OK) == -1)
	{
		perror("access");
		return -1;
	}
	return 0;
}

/*文件是否可读*/
int is_Readable(char *file)
{
	if(access(file,R_OK)==-1)
	{
	    printf("No read permission for '%s' file\n",file);
	    return -1;
	}
	return 0;
}

/*文件是否为目录文件*/
int is_Dir(char *file)
{
    /*获取文件状态信息*/
	struct stat st;	
	if(stat(file,&st)==-1){perror("stat");exit(3);}
	
	/*判断是否是目录文件*/
	if(S_ISDIR(st.st_mode)){return 0;}
	return -1;
}

/*文件到文件拷贝*/
void copy_file(char *src_file,char *dst_file)
{
	char choice;		// 用户意愿
	int src_fd,dst_fd;	// 记录源文件描述符,目标文件描述符
	int rd,wr;			// 实际读的字节数,写的字节数
	int buf[SIZE];		// 存放读写的内容
	struct stat st;		// 记录目标文件状态信息
	int ret=-1;			// 记录获取目标文件状态信息是否成功
	int flag=1;
	
	/*打开源文件*/
	src_fd=open(src_file,O_RDONLY);
	if(src_fd==-1){perror("open");exit(4);}
	
	/*打开目标文件,若不存在,则根据用户意愿创建目标文件*/
	if(access(dst_file,F_OK) == -1)
	{
		perror("access");
		
		while(flag)
		{
			printf("Is create '%s' file ?(Y/N):",dst_file);
			scanf("%c",&choice);
			switch(choice)
			{
				case 'N':
				case 'n':
					exit(0);
				case 'Y':
				case 'y':
					umask(0000);	// 临时改变umask的值
					dst_fd=open(dst_file,O_RDWR|O_CREAT,0666);
					
					if(dst_fd==-1){perror("open");exit(5);}
					printf("Create successfully !\n");
					flag=0;
					break;
				default:
					printf("Input error !\n");
					break;
			}
		}
	}else{		// 目标文件存在
			
			ret=stat(dst_file,&st);	// 获取目标文件状态信息
			if(ret==-1)
			{
				perror("stat");
				exit(6);
			}
			
			/*目标文件不为空,根据用户意愿覆盖文件*/
			if(st.st_size>0)
			{
				char choice;	// 用户意愿
				int flag=1;
				
				while(flag)
				{
					printf("Do you want to overwrite '%s' file ?(Y/N):",dst_file);
					scanf("%c",&choice);
					switch(choice)
					{
						case 'N':
						case 'n':
							exit(0);
						case 'Y':
						case 'y':
							dst_fd=open(dst_file,O_RDWR|O_TRUNC);
							if(dst_fd==-1)
							{
								perror("open");
								exit(8);
							}
							flag=0;
							break;
						default:
							printf("Input error !\n");
							break;
					}
				}	
			}else	// 目标文件为空
			{
				dst_fd=open(dst_file,O_RDWR);
				if(dst_fd==-1){perror("open");exit(9);}
			}	
		}
	
	/*拷贝源文件内容到目标文件中*/
	while(1)
	{
		/*要求从源文件中每次读出SZIE字节内容*/
	    rd=read(src_fd,buf,SIZE);
		if(rd==-1)
		{
			printf("Read failure about '%s' file\n",src_file);
			exit(8);
		}
		
		/*实际读出字节数为0,表明拷贝完成*/
		if(rd==0){printf("Copy successfully !\n");break;}
		
		/*要求每次写入rd字节内容到目标文件*/
		wr=write(dst_fd,buf,rd);
		if(wr==-1)
		{
			printf("Write failed about '%s' file\n",dst_file);
			exit(9);
		}			
	}

	/*完成相关文件操作后,关闭文件*/
	close(src_fd);
	close(dst_fd);
	exit(0);
}


/*字符串连接*/
char* str_contact(char* src_file,char* dst_dir)
{
	char* string;
	
	/*src_file的长度+dst_dir的长度+\0*/
	string=(char*)malloc(strlen(src_file)+strlen(dst_dir)+1);
	
	/*对开辟内存空间失败进行处理*/
	if (string == NULL ) { printf("Out of memory !\n"); exit(1); }
	
	memset(string, 0, strlen(src_file)+strlen(dst_dir)+1);	// 初始化string
	strcat(string,src_file);
	strcat(string,dst_dir);//字符串拼接
	
	return string;
}


int main(int argc,char *argv[])
{	

	/*程序输入的参数是否正确*/
	if(argc < 3)
	{
		printf("Usage:./copy_file src_file1 src_file2 ...  dst_file\n");
		exit(1);
	}
	
	if(argc==3)
	{
		/*文件到文件的拷贝*/
		if(is_Exist(argv[1])==-1){exit(2);}	// 源文件存在
		if(is_Dir(argv[1])==0){exit(3);}	// 源文件非目录文件
		if(is_Readable(argv[1])==-1){exit(4);}	// 源文件可读 
		
		if(is_Exist(argv[2])==-1)	// 目标文件不存在
		{
			copy_file(argv[1],argv[2]);		// 拷贝文件
		}else{	// 目标文件存在
			
			if(is_Dir(argv[1])==-1)	// 目标文件非目录文件
			{
			  copy_file(argv[1],argv[2]);	 // 拷贝文件(文件->文件)
			}else{	// 目标文件是目录文件
				
				/*文件到目录的拷贝*/
				argv[2]=str_contact(argv[1],"/"); 
				argv[2]=str_contact(argv[1],argv[2]); // 拼成生成文件路径
				copy_file(argv[1],argv[2]);	 // 拷贝文件(文件->目录下)	
			}	
		}	
	}else{
		
		/*多个文件拷贝到目标目录下*/
		for(int i=1;i<argc-1;i++)
		{
			if(is_Exist(argv[i])==-1){exit(2);}	// 源文件存在
			if(is_Dir(argv[i])==0){exit(3);}	// 源文件非目录文件
			if(is_Readable(argv[i])==-1){exit(4);}	// 源文件可读
		}
		
		/*目标文件存在且为目录文件*/
		char *temp=argv[argc-1];
		if(is_Exist(argv[argc-1])==0&&is_Dir(argv[argc-1])==0)
		{
				for(int i=1;i<argc-1;i++)
				{
					/*文件到目录的拷贝*/
					argv[argc-1]=str_contact(argv[i],argv[argc-1]); // 拼成生成文件路径
					copy_file(argv[i],argv[argc-1]);	 // 拷贝文件(文件->目录下)	
				}
					
		}else{
			printf("'%s' ERROR !\n",temp);
			exit(5);
		}	
	}
	
	exit(0);
}

运行结果

运行结果

任务二

编写C程序完成:创建一个新文件,输入一段数据,然后随机移动指针接着插入一段数据。完成后,查看该文件的大小和内容。

相关代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#define SIZE 4	// 4字节

/*接收用户输入的字符/字符串,按回车键结束输入*/
char* inputStr()
{
	char* string;	// 用户输入的内容
	char ch;	// 用户输入的单个字符
	int i = 0;	// 用户输入的字符数量
	int count = 0;	// 字符指针string扩充空间的次数

	string = (char*)malloc(sizeof(char) * SIZE + 1);	// 开辟存放SIZE+1字节的内存空间
	
	
	/*对开辟内存空间失败进行处理*/
	if (string == NULL ) { printf("Out of memory !\n"); exit(1); }

	memset(string, 0, sizeof(char) * SIZE + 1);	// 初始化string
	printf("Please input content:");	// 提示用户输入

	/*接收用户输入*/
	while ((ch = getchar()) != '\n')
	{
		string[i] = ch;
		i++;

		/*若开辟的内存空间已满,则动态扩充空间大小*/
		if (i % SIZE == 0)
		{   
			string = (char*)realloc(string, sizeof(char) * SIZE * (i / SIZE + 1) + 1);
			count++;
			
			/*对开辟内存空间失败进行处理*/
			if (string == NULL) { printf("Out of memory !\n"); exit(1); }

			memset(string+SIZE*count, 0, sizeof(char) * SIZE + 1);	//初始化新增部分空间
		}
	}

	printf("Input successfully !\n");
	return string;
}

int main(int argc,char *argv[])
{
	char *str1;		// 用户开始写入的数据
	char *str2;		// 用户要插入的数据
	char *buf;		// 存放读取的文件内容
	int size=0;		// 记录文件大小
	int insert;		// 用户选择插入位置
	int fd=-1;		// 记录目标文件描述符
	int wr=-1;		// 实际写入的字节数
	int rd=-1;		// 实际读取的字节数
	int ret=-1;		// 记录文件偏移量
	
	/*程序输入的参数是否正确*/
	if(argc !=2)
	{
		printf("Usage:./create_file new_file\n");
		exit(2);
	}
	
	/*目标文件是否存在*/
	if(access(argv[1],F_OK) !=-1)
	{
		printf("The '%s' file already exists !\n",argv[1]);
		exit(3);
	}
	
	/*创建目标文件并赋予ugo=644*/
	fd=open(argv[1],O_RDWR|O_CREAT,0644);
	if(fd ==-1){perror("open");exit(4);}
	
	/*接收用户开始输入的数据*/
	str1=inputStr();
	printf("%s\n", str1);

	/*接收用户要插入的数据*/
	str2=inputStr();
	printf("%s\n", str2);
	
	/*将用户开始输入的数据写入文件*/
	wr=write(fd,str1,strlen(str1));
	if(wr==-1){perror("write");exit(5);}
	
	/*获取插入前文件字节数*/
	ret=lseek(fd,0,SEEK_CUR);	
	if(ret==-1){perror("sleek");exit(6);} 
	size=ret;
	
	/*随机生成插入位置*/
	printf("Before insrting,the file size is %d bytes !\n",size);
	insert=rand()%(size+10)+1;	// 1到size+10之间
	printf("The postion of the insertion is %d !\n",insert);
	
	/*根据随机生成的插入位置插入相关内容*/
	{
		/*在文件尾部或更后面插入内容*/
		if(insert>size)	
		{
			/*将指针移到插入位置*/
			ret=lseek(fd,insert-1,SEEK_SET);
			if(ret==-1){perror("sleek");exit(6);}
			
			/*将插入数据写入文件*/
			wr=write(fd,str2,strlen(str2));
			if(wr==-1){perror("sleek");exit(5);}
			printf("Write succeeded !\n");
		}else{
			
			/*将指针移到插入位置*/
			ret=lseek(fd,insert-1,SEEK_SET);
			if(ret==-1){perror("sleek");exit(6);}
			
			// 开辟存放size-insert+2字节的内存空间
			buf=(char *)malloc(sizeof(char)*(size-insert+1)+1);
			
			/*对开辟内存空间失败进行处理*/
			if(buf==NULL){printf("Out of memory !\n");exit(1);}  
			memset(buf, 0, sizeof(char)*(size-insert+1)+1);	// 初始化buf
			
			/*读取用户插入位置后面的字符*/
			rd=read(fd,buf,(size-insert+1));
			if(rd==-1){perror("read");exit(7);}
			
			/*将指针重新移到插入位置*/
			ret=lseek(fd,insert-1,SEEK_SET);
			if(ret==-1){perror("sleek");exit(6);}
				
			/*将插入数据写入文件*/
			wr=write(fd,str2,strlen(str2));
			if(wr==-1){perror("sleek");exit(5);}
				
			/*将需移动的内容重新写入文件*/
			wr=write(fd,buf,rd);
			if(wr==-1){perror("sleek");exit(5);}
			printf("Write succeeded !\n");			
		}
	 }
	 
	/*获取插入前文件字节数*/
	ret=lseek(fd,0,SEEK_CUR);	
	if(ret==-1){perror("sleek");exit(6);} 
	size=ret;
	printf("After insrting,the file size is %d bytes !\n",size);
	
	close(fd); // 关闭文件
	exit(0);
}

运行结果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值