DAY3 IO进程线程,8种文件IO函数的使用(open,close,write,read,lseek,dup,dup2,stat)

1.当一个程序运行后,系统会默认打开三个文件描述符: 0、1、2(stdin、stdout、stderr);

#include<my_head.h>
int main(int argc, const char *argv[])
{
	printf("stdin的文件描述符:%d\n",stdin->_fileno);
	printf("stdout的文件描述符:%d\n",stdout->_fileno);
	printf("stderr的文件描述符:%d\n",stderr->_fileno);

	return 0;
}

 2.open函数以只写的方式打开文件,给予文件权限0666,并关闭文件(close);

#include<my_head.h>
int main(int argc, const char *argv[])
{
	int fd;  //定义文件描述符

	//以只写方式打开文件
	if((fd=open("./c.txt",O_WRONLY|O_CREAT,0666)) == -1)
	{
		perror("open error");
		return -1;
	}

	//关闭文件
	if(close(fd) == -1)
		printf("文件关闭失败\n");
	else
		printf("文件关闭成功\n");
		
	return 0;
}

 3.使用O_EXCL创建文件,判断文件是否已经存在,如果打开文件时,文件已经存在,则open函数会返回一个EEXIST;

#include<my_head.h>
int main(int argc, const char *argv[])
{
	int fd;  //文件描述符

	if((fd=open("./c.txt",O_RDWR|O_CREAT|O_EXCL,0664)) == -1)  //打开文件
	{
		if(errno == EEXIST)  //若文件存在,将错误码置EEXIST
		{
			printf("文件已存在,无需重复创建\n");
			fd = open("./c.txt",O_RDONLY);
		}else
		{
			perror("open error");
			return -1;
		}
	}

	return 0;
}

 4.向指定文件写入fd写入数据(write),然后读取数据(read),最后把数据写到标准输出文件描述符中(write);

#include<my_head.h>
int main(int argc, const char *argv[])
{
	int fd;  //文件描述符
	
	//只写打开文件
	if((fd=open("./b.txt",O_WRONLY|O_CREAT|O_TRUNC,0664)) == -1)
	{
		perror("open error");
		return -1;
	}
 	printf("fd=%d\n",fd);  //输出文件描述符

	char buf[128] = "hello! how are you?"; 
	write(fd,buf,sizeof(buf));  //向文件中写入数据

	close(fd);  //关闭文件

	//只读方式打开文件
	if((fd=open("./b.txt",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}
	char buf1[36];
	int ret = read(fd,buf1,sizeof(buf1));  //从文件中读取数据放到buf1中

	write(1,buf1,ret);  //将数据写入到标准输出文件描述符中
	puts("");

	close(fd);  //关闭文件

	return 0;
}

5. 使用read、write函数完成两个文件的拷贝;

#include<my_head.h>
int main(int argc, const char *argv[])
{
	int srcfd,tarfd;  //文件描述符

	if(argc != 3)  //判读输入文件个数
	{
		puts("input file error");
		return -1;
	}
	//只读打开srcfd
	if((srcfd=open(argv[1],O_RDONLY)) == -1)
	{
		perror("srcfd open error");
		return -1;
	}

	//只写打开tarfd
	if((tarfd=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664)) == -1)
	{
		perror("tarfd open error");
		return -1;
	}

	char buf[128] = "";
	int ret;  //记录每次读取的字符个数
	//文件拷贝
	while((ret = read(srcfd,buf,sizeof(buf))) != -1 && ret != 0)
	{
		write(tarfd,buf,ret);
	}

	close(srcfd);  //关闭文件
	close(tarfd);

	puts("拷贝成功");

	return 0;
}

 6.利用lseek函数得到文件的大小;

#include<my_head.h>
int main(int argc, const char *argv[])
{
	int fd;  //文件描述符

	//只读打开文件
	if((fd=open("./b.txt",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}

	printf("文件的大小:%ld\n",lseek(fd,0,SEEK_END)); //lseek函数

	close(fd);

	return 0;
}

 7.利用lseek函数得到图片的大小;

#include<my_head.h>
int main(int argc, const char *argv[])
{
	int fd;  //文件描述符
	//只读打开图片
	if((fd=open("../day2/lyy.bmp",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}
	//获取文件头部分的文件大小
	lseek(fd,2,SEEK_SET);

	//读取图片的大小
	int img_size;
	read(fd,&img_size,sizeof(img_size));

	printf("图片的大小:%d\n",img_size);

	close(fd);  //关闭文件

	return 0;
}

 8.关于文件描述符拷贝问题

8.1文件描述符的直接拷贝(fd2=fd1),该过程,没有产生新的文件描述符,两个变量共同使用同一个光标;

#include<my_head.h>
int main(int argc, const char *argv[])
{
	//打开并打印fd1文件描述符
	int fd1;
	if((fd1=open("./d.txt",O_RDWR|O_CREAT|O_TRUNC,0664)) == -1)
	{
		perror("open error");
		return -1;
	}
	printf("fd1=%d\n",fd1);

	int fd2 = fd1;  //直接拷贝文件描述符

	//通过fd1向文件中写入数据
	write(fd1,"hi how are you",strlen("hi how are you"));

	//buf存放fd2读取的数据,如果能读出数据,说明不共享光标
	//如果不能读出数据,说明共享光标
	char buf[6] = "";
	read(fd2,buf,sizeof(buf));  
	
	write(1,buf,sizeof(buf));  //将数据写入到终端

	if(close(fd1) != 0)
	{
		perror("close fd1 errro");
		return -1;
	}
	if(close(fd2) != 0)  //会报错,因为没有生成fd2文件描述符
	{
		perror("close fd2 errro");
		return -1;
	}

	return 0;
}

 8.2使用dup函数进行文件描述符的拷贝,该过程,产生新的文件描述符,两个变量共同使用同一个光标;

#include<my_head.h>
int main(int argc, const char *argv[])
{
	//定义文件描述符
	int fd1,fd2;
	//只读打开fd1
	if((fd1=open("./b.txt",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}
	printf("fd1=%d\n",fd1);

	fd2 = dup(fd1);  //调用文件描述符拷贝函数
	printf("fd2=%d\n",fd2);

	lseek(fd1,6,SEEK_SET);  //通过fd1将光标移动第6个字节处

	if(close(fd1) != 0)  //关闭fd1
	{
		perror("close fd1 errro");
		return -1;
	}

	//buf存放fd2读取的数据,如果读出数据hello,说明不共享光标
	//如果读出数据world,说明共享光标
	char buf[5];
	int ret = read(fd2,buf,sizeof(buf));  
	
	write(1,buf,ret);  //将数据写入到标准输出中
	puts("");

	if(close(fd2) != 0) 
	{
		perror("close fd2 errro");
		return -1;
	}

	return 0;
}

8.3多次使用open函数打开同一个文件,每次使用open函数,都会产生一个新的文件描述符,该过程,产生新的文件描述符,两个变量不共同使用同一个光标; 

#include<my_head.h>
int main(int argc, const char *argv[])
{
	//定义文件描述符
	int fd1,fd2;
	//只读打开fd1
	if((fd1=open("./b.txt",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}
	
	//只读打开fd1, fd1,fd2打开同一个文件
	if((fd2=open("./b.txt",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}

	printf("fd1=%d\n",fd1);
	printf("fd2=%d\n",fd2);

	lseek(fd1,6,SEEK_SET);  //通过fd1将光标移动第6个字节处

	//buf存放fd2读取的数据,如果读出数据hello,说明不共享光标
	//如果读出数据world,说明共享光标
	char buf[5];
	int ret = read(fd2,buf,sizeof(buf));  
	
	write(1,buf,ret);  //将数据写入到标准输出中
	puts("");

	close(fd1);
	close(fd2);

	return 0;
}

 8.4使用dup2函数完成文件描述符的拷贝,该过程,产生新的文件描述符,两个变量共同使用同一个光标; 

#include<my_head.h>
int main(int argc, const char *argv[])
{
	//定义文件描述符
	int fd1,fd2;
	//只读打开fd1
	if((fd1=open("./c.txt",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}
	
	//读写打开fd2
	if((fd2=open("./b.txt",O_RDONLY)) == -1)
	{
		perror("open error");
		return -1;
	}

	printf("fd1=%d\n",fd1);
	printf("fd2=%d\n",fd2);

	//操作结束后,fd1和fd2都指向fd2原本指向的文件
	dup2(fd2,fd1);

	printf("fd1=%d\n",fd1);
	printf("fd2=%d\n",fd2);

	lseek(fd1,6,SEEK_SET);  //通过fd1将光标移动第6个字节处

	//buf存放fd2读取的数据,如果读出数据hello,说明不共享光标
	//如果读出数据world,说明共享光标
	char buf[5];
	int ret = read(fd2,buf,sizeof(buf));  
	
	write(1,buf,ret);  //将数据写入到标准输出中
	puts("");
 
	close(fd1);
	close(fd2);

	return 0;
}

 9.使用dup2函数,将stdout改为日志文件;

#include<my_head.h>
int main(int argc, const char *argv[])
{
	//定义文件描述符
	int fd1;
	//读写打开fd1
	if((fd1=open("./b.txt",O_RDWR)) == -1)
	{
		perror("open error");
		return -1;
	}
	printf("fd1=%d\n",fd1);
	
	dup2(fd1,1);  //将stdou改为日志文件

	printf("李白\n");
	printf("苏轼\n");
	printf("杜甫\n");

	close(fd1);

	return 0;
}

10.使用stat 函数获取文件状态;

#include<my_head.h>

int main(int argc, const char *argv[])
{
	struct stat sb;  //文件状态的变量
	
	stat("b.txt",&sb);  //调用文件状态函数,获取文件状态

	printf("inode:%ld\n",sb.st_ino);  //文件的iNode号
	printf("type:%#o\n",sb.st_mode&S_IFMT);  //文件的类型
	printf("mode:%#o\n",sb.st_mode&0777);  //文件的权限


	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值