歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 多線程實現文件拷貝(Linux下C++)

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

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

程序運行截圖:



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

Copyright © Linux教程網 All Rights Reserved