libtar 和 libz 的使用
用c代码生成 tar.gz 文件 实现的功能和 tar -zcf 命令一样
大概流程为
1、先用libtar相关函数对某个目录生成tar文件
2、然后对tar文件进行压缩
//tarFile -- like /home/user/test.tar
int tb_comparss_dir(char* srcDir, char* tarFile)
{
TAR *pTar;
char extractTo[] = ".";
char desFile[FILE_PATH_LEN] = { 0 };
char szBuf[10000] = { 0 };
ssize_t read_len;
FILE* tarFd;
gzFile gzFd;
memset(desFile, 0, sizeof(desFile));
sprintf(desFile, "%s.gz", tarFile);
if (tar_open(&pTar, tarFile, NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) < 0)
{
xlog_error(__FILE__, __LINE__, "tar_open[%s] error[%s]", tarFile, strerror(errno));
return -1;
}
if (tar_append_tree(pTar, srcDir, extractTo) < 0)
{
close(tar_fd(pTar));
xlog_error(__FILE__, __LINE__, "tar_append_tree error[%s]", strerror(errno));
return -1;
}
close(tar_fd(pTar));
tarFd = fopen(tarFile, "rb");
if (tarFd == NULL) {
xlog_error(__FILE__, __LINE__, "fopen[%s] error[%s]", tarFile, strerror(errno));
return -1;
}
gzFd = gzopen(desFile, "wb");
if (gzFd == NULL) {
fclose(tarFd);
remove(tarFile);
fprintf(stderr, "gzopen error\n");
xlog_error(__FILE__, __LINE__, "gzopen[%s] error[%s]", tarFile, strerror(errno));
return -1;
}
while ((read_len = fread(szBuf, 1, 10000, tarFd)) > 0)
{
gzwrite(gzFd, szBuf, read_len);
}
gzclose(gzFd);
fclose(tarFd);
remove(tarFile);
return 0;
} 以上代码进行压缩某个目录,参数srcDir为要打包压缩的某个目录,tarFile 为要打包的文件名(.tar 结尾) 生成的文件最后未.tar.gz
解压缩和压缩过程相反,先解压,再解包
//uncomparss to srcDir
int tb_uncomparss_dir(char* srcDir, char* tarFile)
{
gzFile gzFd;
char szTmpFile[FILE_PATH_LEN] = { 0 };
FILE *fp;
int nReadLen = 0;
char szBuf[10000] = { 0 };
TAR* pTar;
if (strstr(tarFile, "tar.gz") == NULL)
{
xlog_error(__FILE__, __LINE__, "file[%s] is not end with .tar.gz", tarFile);
return -1;
}
if (access(tarFile, F_OK) < 0)
{
xlog_error(__FILE__, __LINE__, "not find file[%s]", tarFile);
return -1;
}
gzFd = gzopen(tarFile, "rb");
if (gzFd == NULL)
{
xlog_error(__FILE__, __LINE__, "gzopen file[%s] err[%s]", tarFile, strerror(errno));
return -1;
}
memset(szTmpFile, 0, sizeof(szTmpFile));
memcpy(szTmpFile, tarFile, strlen(tarFile) - 3); //remove .gz
fp = fopen(szTmpFile, "wb");
if (fp == NULL)
{
gzclose(gzFd);
xlog_error(__FILE__, __LINE__, "open file[%s] err[%s]", szTmpFile, strerror(errno));
return -1;
}
while ((nReadLen = gzread(gzFd, szBuf, 10000)) > 0)
{
fwrite(szBuf, nReadLen, 1, fp);
}
gzclose(gzFd);
fclose(fp);
if (tar_open(&pTar, szTmpFile, NULL, O_RDONLY, 0644, TAR_GNU) < 0)
{
unlink(szTmpFile);
xlog_error(__FILE__, __LINE__, "tar_open[%s] error[%s]", szTmpFile, strerror(errno));
return -1;
}
if (tar_extract_all(pTar, srcDir) < 0)
{
tar_close(pTar);
unlink(szTmpFile);
xlog_error(__FILE__, __LINE__, "tar_extract_all error[%s]", strerror(errno));
return -1;
}
tar_close(pTar);
unlink(szTmpFile);
return 0;
} 请主动忽略 xlog_error()函数
其中makefile 中需要添加动态库 -ltar -lz
libtar.so 可以用yum安装 libtar-devel 这个