电子产业一站式赋能平台

PCB联盟网

搜索
查看: 843|回复: 0
收起左侧

【HarmonyOS HiSpark AI Camera试用连载 】第四次遇见-基于鸿蒙OS的文件拷贝

[复制链接]

2607

主题

2607

帖子

7472

积分

高级会员

Rank: 5Rank: 5

积分
7472
发表于 2020-11-23 01:56:36 | 显示全部楼层 |阅读模式
【HarmonyOS HiSpark AI Camera试用连载 】第四次遇见-基于鸿蒙OS的文件拷贝, 谁? 我! 是你? 是我! 你终于来了! 我终于来了! 你终究是来了? 我终究是来了! 你来干什么! 我来写多一个文件拷贝!

本代码使用鸿蒙OS实现一个文件拷贝操作。 源码中使用三个线程(可以通过宏定义更改线程数,建议根据你电脑或者虚拟机的核心数来更改,不过测试中使用小文件,线程开得多耶看不到明显是速度变化,拷贝大文件就能看到速度变化吗明显)。 本源码仿造迅雷的下载文件机制,通过文件指针的偏移来实现多线程操作,可以在同一时间对文件的多个位置进行拷贝操作,理论上拷贝速度可以达到原来的3倍(决定于宏定义中的数值),实际拷贝速度受制于硬盘读写速度,处理器运算能力,处理器核心数,内核调度策略等一系列外部原因。 一句话,能提速。 文件拷贝过程中,为了防止硬盘空间不足,先读取源文件大小,然后建立新文件,在新文件中偏移指针,大小和源文件相同,在末尾写一个占位符,用来建立一个和源文件一样大小的目标文件,防止拷贝出错。 Ok,话不多说,直接上代码。

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

  •   
  • #define THREADNUM 3
      
  • #define BUFSIZE 1024
      

  •   
  • //多线程文件拷贝程序
      

  •   
  • void *func(void *arg);
      

  •   
  • pthread_mutex_t mutex;
      
  • char *srcfname = NULL;
      
  • char *desfname = NULL;
      
  • off_t fsize, fpos=0;
      

  •   
  • int main(int argc, char **argv)
      
  • {
      
  •         if(argc!=3)
      
  •         {
      
  •                 printf(“error: command + srcfile + desfile\n“);
      
  •                 exit(1);
      
  •         }
      
  •         pthread_t tid[THREADNUM];
      
  •         int i;
      
  •         struct stat finfo;
      
  •         pthread_mutex_init(&mutex, NULL);
      
  •         
      
  •         srcfname = argv[1];
      
  •         desfname = argv[2];
      
  •         printf(“srcfname:%s“,srcfname);
      
  •         printf(“desfname:%s“,desfname);
      
  •         int fds = open(srcfname, O_RDONLY);
      
  •         if(fds<0)
      
  •         {
      
  •                 perror(“open()“);
      
  •                 exit(1);
      
  •         }
      
  •         int fdd = open(desfname, O_WRONLY | O_CREAT, 0666);
      
  •         stat(srcfname, &finfo);//获取源文件详细信息
      
  •         fsize = finfo.st_size;
      
  •         lseek(fdd, fsize-1, SEEK_SET);//偏移目标文件指针到源文件的大小
      
  •         write(fdd, “\0“, 1);//写一个字符在末尾占位
      

  •   
  •         for(i=0;i<THREADNUM;i++)//创建多线程
      
  •         {
      
  •                 pthread_create(&tid, NULL, func, NULL);
      
  •         }
      
  •         
      
  •         for(i=0; i<THREADNUM; i++)//线程收尸
      
  •         {
      
  •                 pthread_join(tid, NULL);
      
  •         }
      

  •   
  •         close(fds);
      
  •         close(fdd);
      
  •         pthread_mutex_destroy(&mutex);//摧毁互斥量
      
  •         exit(0);
      
  • }
      

  •   

  •   
  • void *func(void *arg)
      
  • {
      
  •         int fds, fdd, flag=0, rdcount=0;
      
  •         off_t myfpos;
      
  •         char buf[BUFSIZE];
      
  •         size_t res;
      
  •         fds = open(srcfname, O_RDONLY);
      
  •         if(fds<0)
      
  •         {
      
  •                 perror(“open()“);
      
  •                 pthread_exit(NULL);
      
  •         }
      
  •         fdd = open(desfname, O_WRONLY);
      

  •   
  •         //拿到各个线程自己该偏移的位置
      
  •         pthread_mutex_lock(&mutex);
      
  •         myfpos = fpos;
      
  •         fpos += (fsize/THREADNUM);
      
  •         if((fsize/THREADNUM)*(THREADNUM-1) == myfpos)
      
  •                 flag=1;//标记最后一个拿到任务的线程(特殊)
      
  •         pthread_mutex_unlock(&mutex);
      
  •         
      
  •         lseek(fds, myfpos, SEEK_SET);
      
  •         lseek(fdd, myfpos, SEEK_SET);//将文件指针偏移到相应的位置(处理自己的那一部分)
      

  •   
  •         while(1)
      
  •         {
      
  •                 res = read(fds, buf, BUFSIZE);
      
  •                 rdcount+=res;
      
  •                 if(res==0) break;
      

  •   
  •                 write(fdd, buf, res);
      
  •                 if(rdcount >= (fsize/THREADNUM))
      
  •                 {
      
  •                         if(flag==0) break;
      
  •                 }
      
  •         }
      
  •         
      
  •         close(fds);
      
  •         close(fdd);
      
  •         pthread_exit(NULL);
      
  • }
      


复制代码 关于文件修改和文件烧录参考 https://bbs.elecfans.com/jishu_2001813_1_1.html <span] https://bbs.elecfans.com/jishu_2008062_1_1.html 运行结果 <span]

1.png (1.98 KB, 下载次数: 0)

下载附件  保存到相册  

10 分钟前 上传

2.png (9.57 KB, 下载次数: 0)

下载附件  保存到相册  

10 分钟前 上传 注意,该程序在执行过程中提示需要权限,并且在执行的时候需要加上源文件路径和目标文件路径,不写路径将报错并退出。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表