1.IO效率问题
当你要一次读取大小从从0到某个值效率会增加,但是到达某一个值后效率会减少。
time +可执行程序
会得到三个时间 user :在用户层面的时间 sys :在系统调用层面的时间 real
real=uer+sys+其他因素时间
用户要求user时间 程序要求user +sys
实验找一个3G到5G的文件把bufsize从128到16MB
real sys user时间列一个表。
在程序中while(){读取; count++;}printf("%d",count);
①查看性能的最佳点
②bufsize到达16MB时程序会有上面现象。:段错误。
所以首先我们该如何创建一个空洞文件呢?
代码:
#include "stdio.h"
#include "unistd.h"
#include "fcntl.h"
#include "stdlib.h"
int main()
{
int fp;
long ret;
fp=open("file_4g",O_WRONLY|O_CREAT|O_TRUNC,0666);
if(fp<0)
{
perror("open()");
exit(1);
}
write(fp,"hello",5);
ret= lseek(fp,1024*1024*1024,SEEK_CUR);
if(ret<0)
{
perror("lseek()");
exit(1);
}
ret= lseek(fp,1024*1024*1024,SEEK_CUR);
if(ret<0)
{
perror("lseek()");
exit(1);
}
ret= lseek(fp,1024*1024*1024,SEEK_CUR);
if(ret<0)
{
perror("lseek()");
exit(1);
}
ret= lseek(fp,1024*1024*1024,SEEK_CUR);
if(ret<0)
{
perror("lseek()");
exit(1);
}
write(fp,"world",5);
close(fp);
exit(0);
}
使用ls -lh file_4g来查看文件的大小
使用du -h file_4g来查看在磁盘所占大小 8k系统只是存储一些信息看它有多少个\0注意不是‘\0’
使用od -c 来打印创建的文件中的内容
cat +空洞文件是只会输出一个hello,因为文件太大了。
上面是我测试的8M的时候出现段错误。但是上面时候出现效率最好不能确定。
结论是会在blocksize的整倍数|扇区的整倍数的时候(4K)效率最好
这个是网上的结论:
文章部分转载Linux探秘之I/O效率 - bakari - 博客园 (cnblogs.com)
2.文件共享
多个任务共同操作一个文件或者协同完成任务。
这里用一个面试题来解释。
面试题:删除一个文件的第十行。
思路1找到第10行的行首以及11行的行首,从第11行开始往前面覆写
while(1)
{
lseek(11) +read+lseek(10)+write
}最后多出来的长度就是第10行长度,将最后多的第10行长度去掉。
思路2:打开一个文件打开两次,第一次打开找到第11行行首进行读,第二次打开找到第10行首写。
补充两个函数int ftruncate(int fd,off_t length);将写入模式打开的文件进行截取成length大小的。
int truncate(const char *path ,off_t length);将未打开的文件截取。
程序:使用文件io删除某一行
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
int main(int argc,char *argv[])
{
if(argc<3)
{
fprintf(stderr,"Usage : %s <destfile>",argv[0]);
exit(1);
}
int argc3;
FILE* fp,*fd;
int count=0;
char *p=NULL;
int fpp;
int flag=1;
int ret=1;
int sum=0,m=0;
char buf[512]="\0";
sscanf(argv[2],"%d",&argc3);
if(argc3<0)
{
printf("请输入正整数");
exit(1);
}
fd=fopen(argv[1],"r");
if(fd==NULL)
{
perror("fopen()");
exit(1);
}
fp=fopen(argv[1],"r+");
if(fp==NULL)
{
perror("fopen()");
exit(1);
}
ret= fseek(fd,0,SEEK_SET);
if(ret<0)
{
printf("设置文件指针位置错误1");
exit(1);
}
while(fgets(buf,512,fd)!=NULL)
{
sum=sum+strlen(buf);
++count;
}
if(count<argc3)
{
printf("文件行数太少");
fclose(fd);
fclose(fp);
exit(1);
}
printf("文件行数为:%d \n",count);
ret=fseek(fp,0,SEEK_SET);
if(ret<0)
{
printf("文件位置指针设置错误");
exit(1);
}
ret =fseek(fd,0,SEEK_SET);
if(ret<0)
{
printf("文件位置设置错误");
exit(1);
}
count=0;
while(count<(argc3-1))
{
p=fgets(buf,512,fp);
if(p==NULL)
{
printf("得到某一行出错1");
exit(1);
}
count++;
}
count=0;
while(count<argc3)
{
p=fgets(buf,512,fd);
if(p==NULL)
{
printf("得到某一行出错2");
exit(1);
}
count++;
if(count ==argc3)
m=strlen(buf);
}
while(fgets(buf,512,fd)!=NULL)
{
flag=fputs(buf,fp);
if(flag==EOF)
{
printf("放入字符出错");
exit(1);
}
}
printf("%d ",argc3);
fpp = fileno(fp);
if(ftruncate(fpp, (sum-m))<0)
{
perror("");
exit(1);
}
fclose(fd);
fclose(fp);
exit(0);
}
程序:使用系统IO删除某一行头文件上面的头文件一样
#include "main.h"
int main(int argc,char **argv)
{
printf("必须保证要裁减的文件存在\n");
if(argc<3)
{
fprintf(stderr,"Usage :%s <destfile> <大于零的数>",argv[0]);
exit(1);
}
int ret;
int fd,fp;
long sum=0,m=0;
char str[2]={0};
int pos=0;
sscanf(argv[2],"%d",&ret);
if(ret<0)
{
printf("第二个参数请输入正整数");
}
fd= open(argv[1],O_RDONLY);
if(fd<0)
{
perror("open()");
exit(1);
}
fp=open(argv[1],O_RDWR);
if(fp<0)
{
perror("open()");
exit(1);
}
lseek(fd,0,SEEK_SET);
lseek(fp,0,SEEK_SET);
while(1)
{ if(pos>=ret) break;
if(read(fd,str,1)==0)break;
if(pos==(ret-1))
m++;
if(str[0]=='\n')
pos++;
sum++;
}
if(pos<ret)
printf("文件行数太少");
pos=0;
while(1)
{
if(pos>=(ret-1)) break;
if(read(fp,str,1)==0)break;
if(str[0]=='\n')
pos++;
}
while(1)
{
if(read(fd,str,1)==0) break;
sum++;
write(fp,str,1);
}
printf("%ld\n",sum);
printf("%ld\n",m);
ftruncate(fp,(sum-m));
close(fp);
close(fd);
exit(0);
}