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