源码:windows文件分割与合并

来源:互联网 发布:衣服挂件饰品淘宝网 编辑:程序博客网 时间:2024/06/10 23:04
#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;}

3 0