0
点赞
收藏
分享

微信扫一扫

大文件切分为2M的小文件


* main.cpp

#include <sys/stat.h>
#include <cstring>
#include <cstdio>
#include <cerrno>

#define SPLIT_SIZE 2097152
#define BUF_SZ 1024

#ifndef ENOENT
#define ENOENT 2
#endif
#ifndef NULL
#define NULL ((void *)0)
#endif
#define nullptr NULL

void usage(char *argv[]) {
    printf("Usage: \r\n%s [in_path] [out_dir]\r\n", argv[0]);
}

int makeDir(char *toDir) {
    int ret = 0;
    struct stat statBuf = {};
    ret = ::stat(toDir, &statBuf);
    if (ret == ENOENT || ret == -1) {
        ret = mkdir(toDir, 0755);
        if (ret != 0) {
            fprintf(stderr, "Error(%d) making dir %s: %s",
                    ret, toDir, strerror(ret));
            return ret;
        }
    } else if (ret != 0) {
        fprintf(stderr, "error stat(%d): %s", ret, strerror(ret));
    }
    return ret;
}

int main(int argc, char *argv[]) {
    // 接收参数: 源文件, 目的目录
    char fromPath[256], toDir[256] = {'\0'};
    if (argc < 2) {
        usage(argv);
    }
    strncpy(fromPath, argv[1], 256);
    if (argc < 3) {
        strcpy(toDir, "./out");
    } else {
        strcpy(toDir, argv[2]);
    }
    // 创建目的目录
    int ret = makeDir(toDir);
    if (ret != 0) {return ret;}
    // 打开源文件
    FILE *ffp, *tfp = nullptr;
    ffp = fopen(fromPath, "r");
    // 目的文件路径
    char toName[16] = {'\0'};
    char toPath[256] = {'\0'};
    strcpy(toPath, toDir);
    strcat(toPath, "/000.txt");
    // 创建第0个目的文件
    tfp = fopen(toPath, "w");
    if (tfp == nullptr) {
        fprintf(stderr, "ERROR open \"%s\"(%d):%s\n",
                toPath, errno, strerror(errno));
        return errno;
    }
    size_t fileSize = 0;
    size_t nRead, nToW;
    char buf[1024] = {'\0'};
    int seq = 0;
    do {
        nRead = fread(buf, 1, BUF_SZ, ffp);  // sizeof(char)

        if (fileSize + nRead < SPLIT_SIZE) {
            // 目的文件大小再写一次还没有到SPLIT_SIZE,接着上一个目的文件写入
            nToW = nRead;
        } else if (fileSize < SPLIT_SIZE) {
            // 这次写入后 > SPLIT_SIZE
            nToW = SPLIT_SIZE - fileSize;
            // 源文件回退在buf中多读取的字节数
            fseek(ffp, nRead - nToW, SEEK_CUR);
        } else {
            nToW = nRead;
            // 新建一个目的文件写入
            fclose(tfp);
            tfp = nullptr;
            bzero(toPath, 256);
            strcpy(toPath, toDir);
            sprintf(toName, "/%03d.txt", ++seq);
            strcat(toPath, toName);
            tfp = fopen(toPath, "w");
            if (tfp == nullptr) {
                fprintf(stderr, "ERROR reopen \"%s\"(%d): %s\n",
                        toPath, errno, strerror(errno));
                return errno;
            }
            fileSize = 0;
        }
        fileSize += fwrite(buf, 1, nToW, tfp);
    } while (!feof(ffp) && nRead > 0);

    fclose(ffp);
    fclose(tfp);
    return 0;
}

* CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(cut2m)

set(CMAKE_CXX_STANDARD 98)

add_executable(cut2m main.cpp)

====================[ Build | cut2m | Debug ]===================================
C:\Windows\system32\wsl.exe --distribution Ubuntu --exec /bin/bash -c "export CLION_IDE=TRUE && export CLICOLOR_FORCE=1 && export TERM=xterm && export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' && export JETBRAINS_IDE=TRUE && cd /mnt/e/CLionProjects/cut2m/cmake-build-debug && /usr/bin/cmake --build /mnt/e/CLionProjects/cut2m/cmake-build-debug --target cut2m -- -j 6"
[100%] Built target cut2m

Build finished
 

举报

相关推荐

0 条评论