关于UNIX的文件I/O补充实例

因为是《UNIX环境高级编程》为主,《UNIX系统编程》为辅,所以从第二本书中,补充一下关于UNIX文件I/O的实例。

1.从文件中读取一行,如果是终端用CRTL+D来标记行文件结束符

#include <unistd.h>
#include <errno.h>

int readline(int filedes,char *buff,int nbytes){
	int numread=0;
	int returnval=0;
	
	while( numread < nbytes-1){
		while( ((returnval=read(filedes,buff+numread,1))==-1) && (errno==EINTR));//break by signal will restar.
		if(returnval==-1){//read error
			perror("file read error .");
			return -1;
		}
		if(returnval==0){//end of file
			return numread;
		}
		if(buff[numread++]=='\n'){//end of line
			buff[numread]='\0';
			return numread;
		}
	}
	errno=EINVAL;
	return -1;
}


2.将一个文件拷贝到另一个文件中去

#include <errno.h>
#include <unistd.h>

#define BLKSIZE 512

//copy dstfd to srcfd
int copyfile(int dstfd,int srcfd){
	char *bp;
	char buff[BLKSIZE];
	int copybytes,readbytes,writtenbytes;
	//read file until end of file
	while(1){
		while( ((readbytes=read(srcfd,buff,BLKSIZE))==-1) && (errno==EINTR));//interupt by signal will restar.
		if(readbytes==-1){//read error.
			perror("Read file error.");
			return -1;
		}
		if(readbytes==0){//read to the end of file.
			break;
		}
		bp=buff;
		while(readbytes>0){
			if(((writtenbytes=write(dstfd,bp,readbytes))==-1) && (errno==EINTR)){
				writtenbytes=0;
			}
			if(writtenbytes == -1){//write error.
				return -1;
			}
			bp+=writtenbytes;
			readbytes-=writtenbytes;
		}
	}
}


3.针对上面的因信号重启read和write函数,写出重启函数r_read,r_write

#include <errno.h>
#include <unistd.h>

ssize_t r_read(int fd,void *buff,size_t nbytes){
	ssize_t retval;
	while( ((retval=read(fd,buff,nbytes))==-1) && (errno==EINTR));
	return retval;
}

ssize_t r_write(int fd,void *buff,size_t nbytes){
	char *bufp;
	size_t bytestowrite;
	ssize_t byteswritten;
	size_t totalbytes;
	
	for(bufp=buff,bytestowrite=nbytes,totalbytes=0;
		bytestowrite>0;
		bufp+=byteswritten,bytestowrite-=byteswritten)
	{
		byteswritten=write(fd,bufp,bytestowrite);
		//这代码没有处理byteswritten<bytestowrite情况
		//如果因为磁盘已满出错,则会一直写但每次都写不进去,死循环
		if( (byteswritten==-1) && (errno != EINTR )){
			return -1;
		}
		else{
			byteswritten=0;
		}
		totalbytes+=byteswritten;
	}
	return totalbytes;
}

//用r_read和r_write重写copyfile函数
#define BLKSIZE 512
int copyfile(int dstfd,int srcfd){
	char buff[BLKSIZE];
	int bytesread,byteswritten;
	int totalbytes=0;
	
	while(1){
		if( (bytesread=r_read(srcfd,buff,BLKSIZE)) <=0){
			break;
		}
		if( (byteswritten=r_write(dstfd,buff,bytesread)) <=0){
			break;
		}
		totalbytes+=byteswritten;
	}
	return totalbytes;
}


4.读入指定字节数

#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

ssize_t readblock(int fd,void *buff,size_t nbytes){
	char *bufp;
	size_t bytestoread,totalbytes;
	ssize_t bytesread;
	
	for(bufp=buff,bytestoread=nbytes,totalbytes=0;
		bytestoread>0;
		bufp+=bytesread,bytestoread-=bytesread)
	{
		bytesread=read(fd,bufp,bytestoread);
		if( (bytesread==0) && (totalbytes==0) ){//read the end of file while the first read.
			return 0;
		}
		if(bytesread==0){//read the end of file but totalbytes < nbytes
			errno=EINVAL;
			return -1;
		}
		if( (bytesread==-1) && (errno!=EINTR) ){
			return -1;
		}
		if(bytesread==-1){//read error : this time of reading is not effective.
			bytesread=0;
		}
		totalbytes+=bytesread;
	}
}


暂时补充这么 几个,12点了,去睡觉了。

keep moving!

你可能感兴趣的:(关于UNIX的文件I/O补充实例)