言之者无罪,闻之者足以戒。 ——《诗序》
因为上面的文章中提到了很多关于写和读的函数,所以这篇文章用上面说到的一些函数来实现一下cat和cp的功能;
1、用fopen()、fclose()、fputc()和fgetc()四个函数来实现cat功能:
#include <stdio.h>
int main(int argc,char *argv[])
{
FILE *fp;
int ret;
if(argc < 2)
{
printf("please input scr file\n");
return -1;
}
fp=fopen(argv[1],"r+");
if(fp==NULL)
{
// printf("open file a.c failure\n");
return -2;
}
while(1)
{
ret=fgetc(fp);
if(feof(fp))
{
// printf("read file %s end\n",argv[1]);
break;
}
fputc(ret,stdout);
}
fclose(fp);
return 0;
}
在这里我说一下程序为什么这样写:
第一步:通过内核的驱动将数据读取到内核的缓存中
第二步:通过应用层的读取函数将数据读到用户空间中
第三步:通过写函数将用户空间的内容写进内核的缓存中
第四步:内核空间的缓存通过驱动程序将数据写到硬盘的显示器中
2、全缓存函数:fread()和fwrite()
size_t fread(void *ptr,size_t size,size_t nmemb,FILE *stream)
功能:全缓存的读函数
第一个参数:读到哪里去
第二个参数:读的内容中,每一个单元所占的字节数
第三个参数:读的内容中,有多少个单元数
第四个参数:从哪里读
总共读的字节数:size*nmemb
返回值:实际读的单元数
size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream)
功能:全缓存的写函数
第一个参数:写的内容
第二个参数:写的内容中,每一个单元所占的字节数
第三个参数:写的内容中,有多少个单元数
第四个参数:写到哪里去
总共写的字节数:size*nmemb
返回值:实际写的单元数
下面直接给出一段代码:
#include <stdio.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello Linux,I am xiaoyi\n";
char readbuf[128]={0};
fp=fopen("./a.c","w+");
if(fp==NULL)
{
printf("open a.c failure\n");
return -1;
}
printf("open a.c sucess\n");
fwrite(buf,sizeof(char),sizeof(buf),fp);
rewind(fp);
fread(readbuf,sizeof(char),sizeof(readbuf),fp);
printf("readbuf:%s",readbuf);
// fflush(fp);
// while(1);
fclose(fp);
return 0;
}
上面的代码可以说明fwrite()函数是有缓存的但不是行缓存,这里要注意的还是写过数据之后直接读是不行的,因为文件流的指针位置不对,所以我们上面的程序中加了rewind(fp)函数当然也可以加fseek(fp,0,SEEK_SET)这两条语句的作用是一样的,都是调整文件流指针的位置
3、用fopen()、fclose()、fputc()和fgetc()四个函数来实现cp功能:
下面直接给出程序:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp,*des_fp;
int ret;
if(argc < 3)
{
printf("please input fp file and des file \n");
return -1;
}
fp=fopen(argv[1],"r");
if(fp==NULL)
{
printf("open file %s failure\n",argv[1]);
return -2;
}
printf("open file %s sucess\n",argv[1]);
des_fp=fopen(argv[2],"w");
if(des_fp==NULL)
{
printf("open file %s failure\n",argv[2]);
return -3;
}
printf("open file %s sucess\n",argv[2]);
while(1)
{
ret=fgetc(fp);
if(feof(fp))
{
printf("read file %s end\n",argv[1]);
break;
}
fputc(ret,des_fp);
}
fclose(fp);
fclose(des_fp);
return 0;
}
用命令:time ./a.out a.c b.c 这样就可以查看执行程序所需要的时间了;
结果如下:
时间太短了,原因就是因为a.c文件有点小,所以执行的时间短了一点。
4、用open()、close()、read()和writec()四个函数来实现cp功能:
下面直接给出代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
int fd,des_fd;
int ret;
char buf[128]={0};
if(argc < 3)
{
printf("please input fp file and des file \n");
return -1;
}
fd=open(argv[1],O_RDONLY);
if(fd < 0)
{
printf("open file %s failure\n",argv[1]);
return -2;
}
printf("open file %s sucess\n",argv[1]);
des_fd=open(argv[2],O_CREAT | O_WRONLY,0777);
if(des_fd < 0)
{
printf("open file %s failure\n",argv[2]);
return -3;
}
printf("open file %s sucess\n",argv[2]);
while(1)
{
ret=read(fd,buf,128);
write(des_fd,fd,ret);
if(ret < 128)
{
printf("read file %s end\n",argv[1]);
break;
}
}
close(fd);
close(des_fd);
return 0;
}
通过上面的两段程序我们就可以比较出标准IO与文件IO之间对内核、用户缓存以及真正用时之间的对比,你会发现标准IO在用户缓存和真正用时两个方面的时常都比文件IO用时长,只有内核用时比文件IO短(a.c用足够大才能对比出来)
5、用fopen()、fclose()、fputs()和fgets()四个函数来实现cp功能:
下面直接给出代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp,*des_fp;
int ret;
char buf[128]={0};
if(argc < 3)
{
printf("please input fp file and des file \n");
return -1;
}
fp=fopen(argv[1],"r");
if(fp==NULL)
{
printf("open file %s failure\n",argv[1]);
return -2;
}
printf("open file %s sucess\n",argv[1]);
des_fp=fopen(argv[2],"w");
if(des_fp==NULL)
{
printf("open file %s failure\n",argv[2]);
return -3;
}
printf("open file %s sucess\n",argv[2]);
while(1)
{
fgets(buf,128,fp);
if(feof(fp))
{
printf("read file %s end\n",argv[1]);
break;
}
fputs(buf,des_fp);
}
fclose(fp);
fclose(des_fp);
return 0;
}
对于上面的程序我也没什么说的了,因为这类的程序本篇文章已经说得很多了,之所以一直还在写是想找到一种最快的方式,为以后实现这一功能做一个铺垫。
6、用fopen()、fclose()、fread()和fwrite()四个函数来实现cp功能:
下面直接给出代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp,*des_fp;
int ret;
char buf[128]={0};
if(argc < 3)
{
printf("please input fp file and des file \n");
return -1;
}
fp=fopen(argv[1],"r");
if(fp==NULL)
{
printf("open file %s failure\n",argv[1]);
return -2;
}
printf("open file %s sucess\n",argv[1]);
des_fp=fopen(argv[2],"w");
if(des_fp==NULL)
{
printf("open file %s failure\n",argv[2]);
return -3;
}
printf("open file %s sucess\n",argv[2]);
while(1)
{
ret=fread(buf,sizeof(char),sizeof(buf),fp);
if(ret < 128)
{
printf("read file %s end\n",argv[1]);
break;
}
fwrite(buf,sizeof(char),ret,des_fp);
}
fwrite(buf,sizeof(char),ret,des_fp);
fclose(fp);
fclose(des_fp);
return 0;
}
到这为止,我们就把四组读写函数的读写速度全部用程序表示了出来,最后得出的效率是:
效率 | 最快 |
很快 |
快 |
慢 |
fread、fwrite |
fgets、fputs |
fgetc、fputc |
read、write |
最后分享一句话与大家共勉:
不积跬步,无以至千里;不积小流,无以成江海 ——《劝学》