歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

多線程實現文件拷貝(Linux下C++)

我們應該都用過迅雷這種下載工具吧,迅雷下載工具中運用了多線程下載。多線程文件拷貝是實現多線程下載的基礎,下面給出了多線程文件拷貝的實現代碼:
  1. //copyfile.cc   
  2. #include <iostream>   
  3. #include <cstring>   
  4. #include <stdio.h>   
  5. #include <sys/types.h>   
  6. #include <sys/stat.h>   
  7. #include <fcntl.h>   
  8. #include <unistd.h>   
  9. #include <pthread.h>   
  10. using namespace std;  
  11.   
  12. /************************************ 
  13.  *使用指定線程實現從文件的拷貝 
  14.  *創建時間:2011.07.28 
  15.  *修改時間:2011.07.29 
  16.  *作者:hahaya 
  17.  ***********************************/  
  18.   
  19. //最大使用的線程數   
  20. const int MAX_THREADS = 5;  
  21.   
  22. typedef struct TAG_INFO  
  23. {  
  24.     char *fromfile;                 //源地址   
  25.     char *tofile;                  //目的地址   
  26.     int num;                      //啟動的第i-1個進程   
  27. }info;  
  28.   
  29. //st_size的類型為__off_t   
  30. int get_size(const char *filename)  
  31. {  
  32.     struct stat st;  
  33.     memset(&st, 0, sizeof(st));  
  34.     stat(filename, &st);  
  35.     return st.st_size;  
  36. }  
  37.   
  38. void* threadDL(void *param)  
  39. {  
  40.     info info1 = *((info*)param);  
  41.       
  42.     FILE *fin = fopen(info1.fromfile, "r+");  
  43.     FILE *fout = fopen(info1.tofile, "w+");  
  44.   
  45.     int size = get_size(info1.fromfile);  
  46.     //將文件指針分別設置在每個線程要讀和寫的位置    
  47.     fseek(fin, size*(info1.num)/MAX_THREADS, SEEK_SET);  
  48.     fseek(fout, size*(info1.num)/MAX_THREADS, SEEK_SET);  
  49.   
  50.     char buff[1024] = {'\0'};  
  51.     int len = 0;  
  52.     int total = 0;  
  53.     while((len = fread(buff, 1, sizeof(buff), fin)) > 0)  
  54.     {  
  55.     fwrite(buff, 1, len, fout);  
  56.     total += len;  
  57.     //如果讀入的數據大於文件總大小除線程總數則停止讀入,因為每個線程要讀或寫的數據就等於文件總大小除線程總數   
  58.     //可能會多寫入一些數據,下一次寫入時會覆蓋多寫入的數據,所以不用擔心   
  59.     if(total > size/MAX_THREADS)  
  60.     {  
  61.         break;  
  62.     }  
  63.     }  
  64.   
  65.     fclose(fin);  
  66.     fclose(fout);  
  67.   
  68. }  
  69.   
  70. int main(int argc, char *argv[])  
  71. {  
  72.     //先創建一個與文件1同樣大小的文件   
  73.     creat(argv[2], 0777);  
  74.     truncate(argv[2], get_size(argv[1]));  
  75.   
  76.     pthread_t pid[MAX_THREADS];  
  77.     info info1;  
  78.     //啟動指定線程數的線程   
  79.     for(int i = 0; i < MAX_THREADS; i++)  
  80.    {  
  81.         memset(&info1, 0, sizeof(info1));  
  82.     info1.fromfile = argv[1];  
  83.     info1.tofile = argv[2];  
  84.     info1.num = i;  
  85.     pthread_create(&pid[i], NULL, threadDL, (void*)&info1);  
  86.     }  
  87.     //等待線程結束   
  88.     for(int j = 0; j < MAX_THREADS; j++)  
  89.     {  
  90.     //pthread_join不能用在創建進程的for循環中,否則創建第一個進程後會等待第一個進程結束後創建第二個進程   
  91.     pthread_join(pid[j], NULL);  
  92.     }  
  93.   
  94.     cout << "file copy success......" << endl;  
  95.     return 0;  
  96.       
  97. }  

程序運行截圖:



復制後的文件是完整的,可以解壓,如下圖:

Copyright © Linux教程網 All Rights Reserved