#include <Windows.h> #include <vector> #include <string> using namespace std;
//判断文件是否存在 bool FileExistsW(const wstring &fn) { WIN32_FIND_DATAW fd; HANDLE hFile = FindFirstFileW(fn.c_str(),&fd); if (hFile != INVALID_HANDLE_VALUE) { ::FindClose(hFile); return true; } return false; } //判断目录是否存在 bool DirectoryExistsW(const wstring &fn) { // return PathFileExistsA(fn.c_str()); DWORD Code = GetFileAttributesW(fn.c_str()); return (Code != INVALID_FILE_ATTRIBUTES) && ((FILE_ATTRIBUTE_DIRECTORY & Code) != 0); } //目录+反斜杠 wstring IncludeTrailingPathDelimiterW(const wstring &path) { wstring s = path; if (s.empty()) return s; if (s[s.length()-1] != L'\\') return s+L"\\"; else return s; } //获取路径的文件名 wstring ExtractFileNameW(const wstring &filestr) { if (filestr.empty()) return L""; for(int i = filestr.length()-1; i>=0; --i) { if (filestr[i] == L'\\') { return filestr.substr(i+1); } } return L""; } std::wstring IntToStrW( const int i ) { wchar_t buf[16]={0}; _itow_s(i,buf,10); return wstring(buf); } inline void IncPtr(void **p,int i) { *p = (void*)((int)*p + i); } //分割文件 bool BreakFile(const wchar_t *fn,unsigned long block_size,const wchar_t *save_path) { if(!FileExistsW(fn)) return false; if(!DirectoryExistsW(save_path)) return false; if(block_size < 1) return false; HANDLE hf = CreateFileW(fn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE == hf) return false; int iblock = 1; wstring fblock = IncludeTrailingPathDelimiterW(save_path)+ExtractFileNameW(fn)+L".part"+IntToStrW(iblock); HANDLE hfw = CreateFileW(fblock.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE == hfw) { CloseHandle(hf); return false; } DWORD dwWrited = 0,dwWritedTemp = 0; DWORD dwToWrite = 0; DWORD dwRemain = 0; unsigned char buf[8192]; DWORD dwReaded = 0; int iseek = 0; void *p = NULL; while(true) { dwReaded = 0; if(FALSE == ReadFile(hf,buf,sizeof(buf),&dwReaded,NULL)) break; if(0 == dwReaded) break; iseek = 0; p = (void*)buf; dwRemain = dwReaded; label_rewrite: if(dwWrited >= block_size) { ::CloseHandle(hfw); ++iblock; fblock = IncludeTrailingPathDelimiterW(save_path)+ ExtractFileNameW(fn)+L".part"+IntToStrW(iblock); hfw = CreateFileW(fblock.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE == hfw) { CloseHandle(hf); return false; } dwWrited = 0; } IncPtr(&p,iseek); dwToWrite = min(dwRemain,block_size - dwWrited); dwWritedTemp = 0; if(FALSE == WriteFile(hfw,p,dwToWrite,&dwWritedTemp,NULL)) break; dwWrited += dwWritedTemp; if(dwRemain > dwWritedTemp) dwRemain = dwRemain - dwWritedTemp; else dwRemain = 0; iseek = dwWritedTemp; if(dwRemain > 0) goto label_rewrite; dwReaded = 0; } ::CloseHandle(hfw); ::CloseHandle(hf); return true; } //合并文件 bool CombineFiles(const vector<wstring> &files,const wstring &destfile) { if(FileExistsW(destfile)) return false; if(files.empty()) return false; HANDLE hf = CreateFileW(destfile.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE == hf) return false; HANDLE hfr = INVALID_HANDLE_VALUE; unsigned char buf[8192]; DWORD dwReaded = 0,dwToWrite = 0,dwWrited = 0,dwRemain = 0,dwWritedTemp = 0; LONGLONG dwFileSize = 0,dwDestSize = 0; LARGE_INTEGER li; void *p=NULL; int iseek = 0; for(size_t i = 0; i<files.size(); ++i) { if(!FileExistsW(files[i])) continue; hfr = CreateFileW(files[i].c_str(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE == hfr) continue; li.QuadPart = 0; if(FALSE == GetFileSizeEx(hfr,&li)) { CloseHandle(hf); return false; } dwDestSize += li.QuadPart; } li.QuadPart = dwDestSize; if(FALSE == SetFilePointerEx(hf,li,NULL,FILE_BEGIN)) { CloseHandle(hf); return false; } if(FALSE == SetEndOfFile(hf)) { CloseHandle(hf); return false; } CloseHandle(hf); hf = CreateFileW(destfile.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE == hf) { hf = 0; return false; } hfr = INVALID_HANDLE_VALUE; for(size_t i = 0; i<files.size(); ++i) { if(!FileExistsW(files[i])) continue; if(INVALID_HANDLE_VALUE != hfr) CloseHandle(hfr); hfr = CreateFileW(files[i].c_str(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if(INVALID_HANDLE_VALUE == hfr) continue; label_read: dwReaded = 0; if(FALSE == ReadFile(hfr,buf,sizeof(buf),&dwReaded,NULL)) continue; if (dwReaded == 0) continue; iseek = 0; p = (void*)buf; dwRemain = dwReaded; label_rewrite: IncPtr(&p,iseek); dwToWrite = dwRemain; dwWritedTemp = 0; if(FALSE == WriteFile(hf,p,dwToWrite,&dwWritedTemp,NULL)) continue; dwWrited += dwWritedTemp; if(dwRemain > dwWritedTemp) dwRemain = dwRemain = dwWritedTemp; else dwRemain = 0; iseek = dwWritedTemp; if(dwRemain>0) goto label_rewrite; goto label_read; } if(INVALID_HANDLE_VALUE!=hfr) CloseHandle(hfr); CloseHandle(hf); return true; }