【无标题】

一、read函数
read系统函数从打开的设备或文件中读取数据,即将数据从外设上经过内核读到用户空间,函数原型如下:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
从 fd 中读取数据到 buf 中,count 是要求读到的字节数。
返回值:如果成功返回zhi的是我成功读到的字节数,输入督导读到文件尾部,返回0,失败返回-1 ,设置errno

fd为相应的文件描述符;buf为用户给定的数据缓冲区,该缓冲不是固定大小的,由count值决定其大小(用户给定,字节数)。如 read( fd , “hello” , 5 ); 此时的void *buf为char *类型。即count为请求读取的字节数(即buf的大小)。该函数的返回值为-1时,表示读取数据失败;返回值>0时,表示读出的字节数;返回值等于0时,表示已经读完了,因此没有数据可读了。
ssize_t为有符号整型,size_t为无符号整型。

二、write函数
write系统函数相反,向打开的设备或文件中写入数据,即将数据从用户空间(I/O缓冲)送到内核,然后刷到外设上。

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
从 buf 中写数据到 fd 中,count 是相求写入的字节数。
这里的buf,相比于read的buf而言,多了一个const。也就是这里的buf,是指消息来源,而前面的read指的是从哪儿来,读到那个buf中去。。read中的buf一定是有操作权限,或者是写的权限。
read返回值,返回值是成功写入的字节个数,如果返回值为0表示什么都没写进去。。由于这些erros中有真错,也有假错,如果是假错是,那么你一定是被阻塞或者非阻塞打断了,所以才会导致写进的个数为0个,,如果失败的话,返回值为-1并且设置errno。

返回值:返回值通常与参数 nbytes相同,否则表示出错。

Linux的lseek函数用来控制一个打开的文件的读写位置,它的函数原型如下:
off_t lseek(int fildes,off_t offset ,int whence);

参数的用法:fildes参数为一个已打开的文件描述符;参数offset为读写位置的位移数,这个位移数是根据参数whence来确定的;whence参数分为下列三种:
SEEK_SET:(文件首)表示offset用来直接设置读写位置。
SEEK_CUR:(文件当前位置)表示以目前的读写位置往后增加offset个位移量。
SEEK_END:(末尾位置)表示将读写位置指向文件尾后再增加offset个位移量。
当whence值为SEEK_CUR或SEEK_END时,参数offet允许负值出现。
当lseek调用成功时返回目前的读写位置,也就是距离文件开头多少个字节。若有错误则返回-1,errno会存放错误代码。下面是几个使用示例:
将读写位置移到文件开头:lseek(myfile, 0, SEEK_SET);
将读写位置移到文件尾:lseek(myfile, 0, SEEK_END);
想要取得目前文件位置:off_t cur=lseek(myfile, 0, SEEK_CUR);
注意:使用lseek函数需要包含以下头文件:

李慧芹老师课程 系统IO与标准IO比较实例课程随堂笔记

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

#define BUFSIZE 1024
int main(int argc,char* argv[])
{
int sfd,dfd;
char buf[BUFSIZE];
int len=0,ret=0,pos=0;
//首先判断命令行传参是否出错
if(argc<3)
{
fprintf(stderr,“Usage…\n”);
exit(0);
}
sfd=open(argv[1],O_RDONLY);//源文件只读方式打开
if(sfd<0)
{
perror(“open()”);
exit(1);
}
dfd=open(argv[2],O_WRONLY|O_CREAT,O_TRUNC,0600);//我要来打开argv[2],然后以只写的方式打开,并且这个文件不一定存在,如果不存在就创建(O_CREAT),如果文件存在就截断(O_TRUNC),如果文件当中用到O_TCREAT,就要给一个权限0600

	if(sfd<0)
	{
		close(sfd);//如果你这儿目标文件dfd打开失败,而你的源文件其实已经打开了,所以这里一定要去close()源文件。
		//防止内存泄漏
		perror("open()");
		exit(1);
	}
	while(1)
	{
		//这里的read和write就变成了,读一块,写一块。。
		//在这个例子中,读是主要的,
		len=read(sfd,buf,BUFSIZE);
	//读谁(读源文件sfd),读到那里去(找一块空间buf,定义数组buf),一次读多少(读BUFSIZE个),返回值是成功读到的字节个数len
		if(len<0)//这里要根据len 的判断,来确定是否跳出当前循环,如果len
		{
			perror("read()");
			break;// 如果这里写exit(),就直接退出进程了,而之前打开的文件没关闭。那么后面你还要执行两次close,那么我这里直接用break,指的是跳出当前循环,后面在执行两次close关闭文件,防止内存泄漏。
		}
		if(len==0)//这时候就跳出循环,这属于读完了
			break;
		
		//我在write的时候,要写进len个字节去,有没有写进去?
			
		while(len>0)//当len的值大于0的时候,我就去执行write,那么你取回来的值,不是从buf中取出的了,而是从前面的数据与buf的累加。
		{
			ret=write(dfd,buf+pos,len);//真实数据从哪里来,从buf来,要写多少个进去。写len个数据进去.......pos的值初始化为0,我第一次写的时候从buf里面的值写内容,要写的是len个字节,假设只写进去了3个len-3=7还剩下7个没写进去,然后我判断len的值大于0,我继续往里面写,从buf+3的位置写
			if(ret<0)
			{
				perror("write()");
				exit(1);//如果ret小于零,说明出错了,这里可以跳出循环,然后到后面执行close,关闭两个v文件;
			}
			pos +=ret;
						//如果ret大于等于0,说明读成功了,我们继续循环
			//我在write的时候,要写进len个字节去,有没有写进去?
			len -=ret;;//如果这个值等于0
		}
	}
	
	//前面成功打开了文件,那么最后一定要关闭文件,防止内存泄漏
	close(dfd);//先关闭目标文件
	close(sfd);//在关闭源文件
	exit(0);

}

//思考:
/*
第一反应是把程序写到现在这个程度,但是其实有点不太好。。
比如说进入循环,假设len读到了个字节, len等于,下面我开始write().我在write函数中,从buf取内容进行写,写个字节,写到dfd文件中去,然后如果write的返回值小于的话,就报错结束。。
但是有这种情况,比如len的值为,我在写个字节的时候,而其实只写进去了3个,那么你看我判断ret的值也不小于0,那么其实你就回去进行下一步read操作了,也就说你凭空丢了7个字节,,你读到了10个字节,写进去3个,也就丢了7个字节,因为你下次去read,这块空间就被覆盖掉了。所以这块应该要在write的时候,应该想到,我 要写进len个字节去,又没写进去。。所以这块我要这么做,,判断如果len-ret等于0,那就没问题,如果不等于0。说明我还要绕回去继续read,所以这块我这里来一个循环,while ,,因该是吧当前的write放在循环中的,,,然后while的参数应该这样构建,当这个len的值大于0。我就去执行write…那你取回来的内容也不是buf中取得,而是buf+ret,是前面所有ret的累加。。所以我定义一个变量pos,,然后在这块写一下,我write的值是buf+pos这么多,pos的值要初始化,初始化为0

我第一次写的时候,是从buf加0位置去写内容,要写进的字节数为10个,假设只写进了3个,,他们两一减。。len的值为7.。回到循坏开头,len的值大于0,,我就继续去read,,我还是往里写,从buf+3(pos)的位置开始,所以这块应该还有pos=pos+ret,,这样的话就不能break了,因为你的break只能跳出内层循环,还依然咋i外层循环中。。所以这块我们直接exit结束进程,,目前我们允许产生小的内存泄漏问题,,所以这个程序写到这块更加严谨。。

diff "src"   "destflie"  比较源文件与目标文件是否相同。

*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值