/**
* Tencent is pleased to support the open source community by making MSEC available.
*
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the GNU General Public License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* https://opensource.org/licenses/GPL-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package msec.org;
/**
*
*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.*;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;
//打包和拆包.tar文件的工具类
public abstract class TarUtil {
private static final int BUFFERSZ = 1024;
//将文件或者目录srcPath打包成一个tar文件,保存在destPath文件
// 用到了递归的方式遍历目录下的文件和目录
public static void archive(String srcPath, String destPath)
throws Exception {
File srcFile = new File(srcPath);
File destFile = new File(destPath);
archive(srcFile, destFile);
}
public static void archive(File srcFile, File destFile) throws Exception {
TarArchiveOutputStream taos = new TarArchiveOutputStream(
new FileOutputStream(destFile));
taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
archive(srcFile, taos, "");
taos.flush();
taos.close();
}
private static void archive(File srcFile, TarArchiveOutputStream taos,
String basePath) throws Exception {
if (srcFile.isDirectory()) {
archiveDir(srcFile, taos, basePath);
} else {
archiveFile(srcFile, taos, basePath);
}
}
private static void archiveDir(File dir, TarArchiveOutputStream taos,
String basePath) throws Exception {
File[] files = dir.listFiles();
if (files.length < 1) {
TarArchiveEntry entry = new TarArchiveEntry(basePath
+ dir.getName() + File.separator);
taos.putArchiveEntry(entry);
taos.closeArchiveEntry();
}
for (File file : files) {
// 递归归档
archive(file, taos, basePath + dir.getName() + File.separator);
}
}
private static void archiveFile(File file, TarArchiveOutputStream taos,
String dir) throws Exception {
boolean is_symbolic = Files.isSymbolicLink(file.toPath());
TarArchiveEntry entry;
if(is_symbolic) {
entry = new TarArchiveEntry(dir + file.getName(), TarArchiveEntry.LF_SYMLINK);
entry.setLinkName(Files.readSymbolicLink(file.toPath()).toString());
}
else {
entry = new TarArchiveEntry(dir + file.getName());
entry.setSize(file.length());
if (file.canExecute()) {
// -rwxr-xr-x
entry.setMode(493);
}
}
taos.putArchiveEntry(entry);
if(!is_symbolic)
IOUtils.copy(new FileInputStream(file), taos);
taos.closeArchiveEntry();
}
//将tar文件srcFile解包在当前目录下
public static void dearchive(File srcFile) throws Exception {
String basePath = srcFile.getParent();
dearchive(srcFile, new File(basePath));
}
public static void dearchive(File srcFile, File destFile) throws Exception {
TarArchiveInputStream tais = new TarArchiveInputStream(
new FileInputStream(srcFile));
dearchive(destFile, tais);
tais.close();
}
private static void dearchive(File destFile, TarArchiveInputStream tais)
throws Exception {
TarArchiveEntry entry = null;
while ((entry = tais.getNextTarEntry()) != null) {
// 文件
String dir = destFile.getPath() + File.separator + entry.getName();
File dirFile = new File(dir);
// 文件检查
fileProber(dirFile);
if (entry.isDirectory()) {
dirFile.mkdirs();
} else if (entry.isSymbolicLink()) {
File target = new File(entry.getLinkName());
Files.createSymbolicLink(dirFile.toPath(), target.toPath());
} else {
boolean executable = (entry.getMode() % 2) == 1;
dearchiveFile(dirFile, tais);
dirFile.setExecutable(executable);
}
}
}
public static void dearchive(String srcPath) throws Exception {
File srcFile = new File(srcPath);
dearchive(srcFile);
}
private static void dearchiveFile(File destFile, TarArchiveInputStream tais)
throws Exception {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
int count;
byte data[] = new byte[BUFFERSZ];
while ((count = tais.read(data, 0, BUFFERSZ)) != -1) {
bos.write(data, 0, count);
}
bos.close();
}
private static void fileProber(File dirFile) {
File parentFile = dirFile.getParentFile();
if (!parentFile.exists()) {
// 递归寻找上级目录
fileProber(parentFile);
parentFile.mkdir();
}
}
}