源码:windows文件分割与合并

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

你可能感兴趣的:(windows,合并,文件分割,文件读写)