windows 合并linux的分卷文件
一般在linux上使用tar命令和split命令对文件进行分卷压缩,在linux上可以用cat命令合并分卷。但在windows上我不知道怎么合并,就写了一个小工具。
程序假设分卷个数小于等于99个,后缀是%02d形式的
传入前缀即可,生成一个前缀的文件,需要提前保证这个文件不存在
比如1.mp4
在linux上分卷压缩成了
1.mp4.gz.00
1.mp4.gz.01
1.mp4.gz.02
1.mp4.gz.03
那么使用方法为
mergefile.exe 1.mp4.gz.
最后会生成一个1.mp4.gz的文件
因为windows的文件不能以.结束,所以就变成了1.mp4.gz
解压这个文件即可
#include <iostream>
#include <string>
#include <string.h>
#include <vector>
#include <stack>
#include <stdio.h>
#include <direct.h>
#include <io.h>
using namespace std;
bool check_args(int argc, char **argv)
{
// 传输的路径参数不能以*结尾,否则cmd会自动补全成对应的匹配文件
// cout<<argc<<endl;
// for(int i=0;i<argc;i++)
// {
// cout<<argv[i]<<endl;
// }
return argc==2;
}
string get_cwd()
{
char buffer[1024];
memset(buffer, '\0', sizeof(buffer));
_getcwd(buffer, 1024);
return buffer;
}
vector<string> split_string(string s, vector<char> cs)
{
vector<string> ans;
string t="";
for(int i=0;i!=s.size();i++)
{
bool flag = 0;
for(int j=0;j!=cs.size();j++)
{
if(s[i]==cs[j])
{
flag=1;
break;
}
}
if(flag&&t.size()>0)
{
ans.push_back(t);
t="";
}
else
{
t+=s[i];
}
}
if(t.size())ans.push_back(t);
t = "";
return ans;
}
string get_file_folder(string file_path)
{
int index = -1;
for(int i=file_path.size()-1;i>=0;i--)
{
if(file_path[i]=='/'||file_path[i]=='\\')
{
index = i;
break;
}
}
string folder_path = "";
for(int i=0;i<index;i++)folder_path+=file_path[i];
return folder_path;
}
string get_file_name_from_file_path(string file_path)
{
int index = -1;
for(int i=file_path.size()-1;i>=0;i--)
{
if(file_path[i]=='/'||file_path[i]=='\\')
{
index = i;
break;
}
}
string file_name = "";
for(int i=index+1;i<file_path.size();i++)
{
file_name+=file_path[i];
}
return file_name;
}
string refine_file_path(string file_path)
{
// 路径有可能是绝对路径。有可能是相对路径。有可能是错误路径
// 首先去掉文件名,拿到文件的文件夹路径
string folder_path = "";
int index = -1;
for(int i=file_path.size()-1;i>=0;i--)
{
if(file_path[i]=='/'||file_path[i]=='\\')
{
index = i;
break;
}
}
for(int i=0;i<index;i++)
folder_path+=file_path[i];
string file_template_name = "";
for(int i=index+1;i<file_path.size();i++)
file_template_name+=file_path[i];
// 此时拿到文件夹路径后,再去除路径中的.和..
vector<string> folder_path_split = split_string(folder_path, {'/', '\\'});
stack<string> folder_path_stack;
for(int i=0;i!=folder_path_split.size();i++)
{
if(folder_path_split[i]==".")continue;
if(folder_path_split[i]==".."&&folder_path_stack.size()>0)
folder_path_stack.pop();
else
folder_path_stack.push(folder_path_split[i]);
}
folder_path = "";
while(folder_path_stack.size())
{
if(folder_path.size())folder_path="/"+folder_path;
folder_path=folder_path_stack.top()+folder_path;
folder_path_stack.pop();
}
if(folder_path.size()==0)folder_path=get_cwd();
return folder_path+"/"+file_template_name;
}
vector<string> get_folder_files(string folder_path)
{
vector<string> files;
_finddata_t fileinfo;
intptr_t handle;
handle = _findfirst((folder_path+"/*").c_str(), &fileinfo);
if (handle == -1) {
printf("path %s is exist\n", folder_path.c_str());
return files;
}
do
{
if (fileinfo.attrib & _A_SUBDIR)
continue;
else
files.push_back(folder_path+"/"+fileinfo.name);
} while (_findnext(handle, &fileinfo) == 0);
_findclose(handle);
return files;
}
inline bool is_file_exists(const std::string& file_path) {
return ( access( file_path.c_str(), F_OK ) != -1 );
}
bool check_merge_files(string file_path, vector<string> files)
{
string file_template_name = get_file_name_from_file_path(file_path);
string folder_path = get_file_folder(file_path);
// 1.mp4.gz*
string first_file_path = folder_path + "/"+ file_template_name+ "00";
string output_file_path = folder_path + "/"+ file_template_name;
return is_file_exists(first_file_path) && (!is_file_exists(output_file_path));
}
void merge_files(string file_path, vector<string> files)
{
string file_template_name = get_file_name_from_file_path(file_path);
string folder_path = get_file_folder(file_path);
// 1.mp4.gz*
const int max_num = 99;
string prefix_file_path = folder_path + "/"+ file_template_name;
string output_file_path = folder_path + "/"+ file_template_name;
int cnt=0;
const int buffsize=2048;
char buff[buffsize];
int read_count=0;
FILE *output_fp = fopen(output_file_path.c_str(), "wb");
if(output_fp==NULL)return;
while(cnt<=max_num)
{
string s_no = to_string(cnt);
if(s_no.size()==1)s_no = "0"+s_no;
string t_file_path = (prefix_file_path + s_no);
if(is_file_exists(t_file_path))
{
FILE *t_fp = fopen(t_file_path.c_str(), "rb");
while(!feof(t_fp))
{
read_count = fread(buff,sizeof(char),buffsize,t_fp);
fwrite(buff,sizeof(char),read_count,output_fp);
}
fclose(t_fp);
}
cnt++;
}
fclose(output_fp);
}
int main(int argc, char **argv) {
if(!check_args(argc, argv))
{
printf("usage: mergerfile.exe 1.mp4.gz.\n");
exit(0);
}
string file_path = refine_file_path(argv[1]);
string folder_path = get_file_folder(file_path);
vector<string> files = get_folder_files(folder_path);
if(!check_merge_files(file_path, files))
{
printf("can't find files like %s, or %s already exists!\n", argv[1], argv[1]);
exit(0);
}
merge_files(file_path, files);
return 0;
}