IO效率问题与文件共享

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);
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值