多线程拷贝文件

1.有时候需要同时处理多个文件,而这几个文件在由于权限问题必须复制到其他目录继续处理,这时候如果文件多了的话,拷贝时间是非常耗时的,这样在用户体验上,即开始处理文件前会有比较长时间的停顿。

/*
 * mul_thread_copy.cpp
 *
 *  Created on: 2013-5-9
 *      Author: hp
 */
#include "mul_thread_copy.h"

//standard
#include "stdio.h"
#include <iostream>
#include <sstream>
#include <algorithm>
#include "windows.h"
#include "winbase.h"
#include <map>
#include <dirent.h>
#include "time.h"
//boost
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/smart_ptr.hpp>
//boostpool 第三方
#include <boost/threadpool.hpp>
#include "threadpool.hpp"

using namespace boost::threadpool;

#define BUF_SIZE 1024 * 1024

void MyCopyFile(const char* inFile, const char* outFile)
{
    FILE *in_file, *out_file;
    char data[BUF_SIZE];
    size_t bytes_in, bytes_out;
    long len = 0;

    if ( (in_file = fopen(inFile, "rb")) == NULL )
    {
        return;
    }
    string str_dist_dir(outFile);
    str_dist_dir = str_dist_dir.substr(0, str_dist_dir.rfind("/"));
    if(access(str_dist_dir.c_str(), F_OK))
    {
    	mkdir(str_dist_dir.c_str());
    }
    if ( (out_file = fopen(outFile, "wb")) == NULL )
    {
        return;
    }

    while ( (bytes_in = fread(data, 1, BUF_SIZE, in_file)) > 0 )
    {
        bytes_out = fwrite(data, 1, bytes_in, out_file);
        if ( bytes_in != bytes_out )
        {
            return;
        }
        len += bytes_out;
    }

    fclose(in_file);
    fclose(out_file);
}


void GetAllFilePathInDir(const string& source_dir, const string& dist_dir,
		map<string, string>& vec_files_path)
{
    DIR *dir = NULL;
    dir = opendir(source_dir.c_str());

    if (!dir)
    {
        return;
    }

    std::string str_source_dir = source_dir;
    if (str_source_dir[str_source_dir.size()-1] != '/')
    {
    	str_source_dir.append("/");
    }
    std::string str_dist_dir = dist_dir;
    if (str_dist_dir[str_dist_dir.size()-1] != '/')
    {
    	str_dist_dir.append("/");
    }

    while(-1 != dir->dd_stat)
    {
        dirent *file_dir;
        file_dir = readdir(dir);
        if (!file_dir || (!strcmp(file_dir->d_name, ".")) || (!strcmp(file_dir->d_name, "..")))
        {
            continue;
        }

        string str_source_path(str_source_dir);
        str_source_path.append(file_dir->d_name);

        string str_dist_path(str_dist_dir);
        str_dist_path.append(file_dir->d_name);

        if (_A_SUBDIR == dir->dd_dta.attrib)
        {
        	GetAllFilePathInDir(str_source_path, str_dist_path,
        			vec_files_path);
        }
        else
        {
        	vec_files_path.insert(map < string, string >::value_type(
        			str_source_path, str_dist_path));
        }
    }  //end while
    closedir(dir);
}

void StartMulThreadCopy(const string& source_dir, const string& dest_dir,
		const int thread_num)
{
	time_t now;
	struct tm *fmt;
	time(&now);
	fmt = localtime(&now);
	char video_file_name[128] = {0};
	sprintf(video_file_name, " %d.%d.%d.%d.%d.%d", fmt->tm_year + 1900, fmt->tm_mon + 1,
			fmt->tm_mday, fmt->tm_hour, fmt->tm_min, fmt->tm_sec);
	cout<<"Start:\t"<<video_file_name<<endl;

	//确定线程数
	int current_thread_num = thread_num;
	int core_num = (int)boost::thread::hardware_concurrency();
	if(core_num < thread_num)
	{
		current_thread_num = core_num;
	}
	pool tp;
	tp.size_controller().resize(current_thread_num);

	//确定文件路径
	//第一个原路径,第二个目标路径
	map<string, string> vec_files_path;
	GetAllFilePathInDir(source_dir, dest_dir, vec_files_path);

	//开始线程
	map<string, string>::iterator it;
	for(it=vec_files_path.begin(); it!=vec_files_path.end(); ++it)
	{
		schedule(tp, boost::bind(&MyCopyFile,
				it->first.c_str(),
				it->second.c_str()));
	}

	tp.wait();

	time(&now);
	fmt = localtime(&now);
	char video_file_name2[128] = {0};
	sprintf(video_file_name2, " %d.%d.%d.%d.%d.%d", fmt->tm_year + 1900, fmt->tm_mon + 1,
			fmt->tm_mday, fmt->tm_hour, fmt->tm_min, fmt->tm_sec);
	cout<<"End:\t"<<video_file_name2<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值