源码: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文件分割与合并

时间: 2024-10-13 12:23:03

源码:windows文件分割与合并的相关文章

c语言文件分割与合并

一.综述 c语言操作文件通过文件指针FILE*,每个要操作的文件必须打开然后才能读写. 注意事项: @1分割与合并文件最好使用二进制模式即"rb"或"wb",这样可以操作任何类型文件 @2FILE 指针一定要进行判空操作即看F == NULL成立不 @3文件用完必须关闭,释放系统资源,因为文件会分配缓冲区,占据内存 1.包含头文件 _CRT_SECURE_NO_WARNINGS表示关闭安全检查 1 #define _CRT_SECURE_NO_WARNINGS 2

java:快速文件分割及合并

文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并.很多高大上的分布式文件系统(比如:google的GFS.taobao的TFS)里,也是按block为单位,对文件进行分割或合并. 看下基本思路: 如果有一个大文件,指定分割大小后(比如:按1M切割) step 1: 先根据原始文件大小.分割大小,算出最终分割的小文件数N step 2: 在磁盘上创建这N个小文件 step 3: 开多个线程(线程数=分割文件数),每个线程里,利用RandomAccessF

java文件分割和合并

package search; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class Split {

(转)java:快速文件分割及合并

文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并.很多高大上的分布式文件系统(比如:google的GFS.taobao的TFS)里,也是按block为单位,对文件进行分割或合并. 看下基本思路: 如果有一个大文件,指定分割大小后(比如:按1M切割) step 1: 先根据原始文件大小.分割大小,算出最终分割的小文件数N step 2: 在磁盘上创建这N个小文件 step 3: 开多个线程(线程数=分割文件数),每个线程里,利用RandomAccessF

.NET Core项目修改project.json来引用其他目录下的源码等文件的办法 &amp; 解决多框架时 project.json 与 app.config冲突的问题

作者: zyl910 一.缘由 项目规模大了后,经常会出现源码文件分布在不同目录的情况,但.NET Core项目默认只有项目目录下的源码文件,且不支持“Add As Link”方式引入文件.这时需要手工修改project.json文件了. 可能是因为最新版本已将 project.json 转为 .csproj,导致我花了一些功夫才找到配置办法,故写了这篇笔记. 二.引用其他目录下的源码等文件的办法 2.1 官网说明 官网的 project.json 和 csproj 属性之间的映射 里简单介绍了

文件分割与合并(Java)

一.文件分割示意图 二.文件合并示意图 方式一:通过文件追加的方式 方式二:通过SequenceInputStream对其他输入流的逻辑串联. 测试RandomAccessFile随机访问文件 package FileSplitMerge; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import IOOthers.FileUtil; /** * RandomAccessFil

delphi 文件分割与合并

流的使用分割与合并文件的函数 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure

python学习——大文件分割与合并

在平常的生活中,我们会遇到下面这样的情况: 你下载了一个比较大型的游戏(假设有10G),现在想跟你的同学一起玩,你需要把这个游戏拷贝给他. 然后现在有一个问题是文件太大(我们不考虑你有移动硬盘什么的情况),假设现在只有一个2G或4G的优盘,该怎么办呢? 有很多方法,例如winrar压缩的时候分成很多小卷,这里不累述. 在学习python之后,我们自己就可以解决这个问题啦. 我们可以自己写一个脚本去分割合并文件,将文件分割成适合优盘大小的小文件,在拷贝,然后再合并. 下面是文件分割脚本: 1 im

Spark笔记--使用Maven编译Spark源码(windows下)

1. 官网下载源码 source code,地址: http://spark.apache.org/downloads.html 2. 使用maven编译: 注意在编译之前,需要设置java堆大小以及永久代大小,避免mvn出现内存溢出的情况. windows下设置:%MAVEN_HOME%\bin\mvn.cmd,将其中的 @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=80