java实现linux文件的解压缩(确保md5sum一致)
package com.xlkh.device.utils; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; public class LinuxTarGzUtil { private static final Logger logger = LoggerFactory.getLogger(LinuxTarGzUtil.class); /**
* 使用Linux命令压缩目录
* @param sourceDirPath 源目录路径(需为Linux路径格式)
* @param outputFilePath 输出文件路径
*/
public static String compress(String sourceDirPath, String outputFilePath) throws IOException {
Path sourcePath = Paths.get(sourceDirPath);
Path outputPath = buildOutputPath(sourcePath, outputFilePath); createParentDir(outputPath); // 构建新的压缩命令(保持MD5一致的关键实现)
String[] cmd = {
"/bin/bash",
"-c",
String.format(
"find %s -exec touch -h -t 197001010000.00 {} \\; && " +
"tar --sort=name --numeric-owner --no-same-permissions -cf - -C %s %s | " +
"gzip -n -f > %s", // 压缩并输出
sourcePath.toAbsolutePath(),
sourcePath.getParent().toAbsolutePath(),
sourcePath.getFileName(),
outputPath.toAbsolutePath()
)
}; return executeCommand(cmd, "压缩");
} /**
* 使用Linux命令解压文件
* @param inputFilePath 压缩文件路径
* @param outputDirPath 解压目录路径
*/
public static String decompress(String inputFilePath, String outputDirPath) throws IOException {
validateTarGzExtension(inputFilePath); // 创建输出目录
Files.createDirectories(Paths.get(outputDirPath)); // 构建解压命令
String[] cmd = {
"/bin/bash",
"-c",
String.format("tar -xzf %s --warning=no-timestamp --no-same-owner -C %s",
Paths.get(inputFilePath).toAbsolutePath(),
Paths.get(outputDirPath).toAbsolutePath())
}; return executeCommand(cmd, "解压");
} private static Path buildOutputPath(Path sourcePath, String outputPathStr) {
Path outputPath = Paths.get(outputPathStr).normalize(); if (Files.isDirectory(outputPath)) {
String sourceDirName = getLastNonEmptyPathPart(sourcePath);
return outputPath.resolve(sourceDirName + ".tar.gz");
}
return outputPath;
} private static void createParentDir(Path path) throws IOException {
Path parent = path.getParent();
if (parent != null && !Files.exists(parent)) {
Files.createDirectories(parent);
logger.info("已创建父目录:{}", parent);
}
} private static void validateTarGzExtension(String filename) {
if (!filename.toLowerCase().endsWith(".tar.gz")) {
throw new IllegalArgumentException("只支持.tar.gz格式文件");
}
} private static String executeCommand(String[] cmd, String operation) throws IOException {
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true); try {
Process process = pb.start();
StringBuilder output = new StringBuilder(); // 读取命令输出
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
} int exitCode = process.waitFor();
if (exitCode != 0) {
throw new IOException(operation + "失败,退出码:" + exitCode + "\n" + output);
} logger.info("{}成功:{}", operation, output);
return operation + "成功"; } catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException(operation + "进程被中断", e);
}
} // 保留原有路径处理方法
private static String getLastNonEmptyPathPart(Path path) {
Path normalized = path.normalize();
int nameCount = normalized.getNameCount(); // 处理根目录特殊情况(如:/app)
if (nameCount == 0) {
String pathStr = normalized.toString();
int lastSeparator = pathStr.lastIndexOf(File.separatorChar);
return lastSeparator > 0 ? pathStr.substring(lastSeparator + 1) : pathStr;
} return normalized.getName(nameCount - 1).toString();
}
}
接口调用:

验证:


package com.xlkh.device.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class LinuxTarGzUtil {
private static final Logger logger = LoggerFactory.getLogger(LinuxTarGzUtil.class);
/**
* 使用Linux命令压缩目录
* @param sourceDirPath 源目录路径(需为Linux路径格式)
* @param outputFilePath 输出文件路径
*/
public static String compress(String sourceDirPath, String outputFilePath) throws IOException {
Path sourcePath = Paths.get(sourceDirPath);
Path outputPath = buildOutputPath(sourcePath, outputFilePath);
createParentDir(outputPath);
// 构建新的压缩命令(保持MD5一致的关键实现)
String[] cmd = {
"/bin/bash",
"-c",
String.format(
"find %s -exec touch -h -t 197001010000.00 {} \\; && " +
"tar --sort=name --numeric-owner --no-same-permissions -cf - -C %s %s | " +
"gzip -n -f > %s", // 压缩并输出
sourcePath.toAbsolutePath(),
sourcePath.getParent().toAbsolutePath(),
sourcePath.getFileName(),
outputPath.toAbsolutePath()
)
};
return executeCommand(cmd, "压缩");
}
/**
* 使用Linux命令解压文件
* @param inputFilePath 压缩文件路径
* @param outputDirPath 解压目录路径
*/
public static String decompress(String inputFilePath, String outputDirPath) throws IOException {
validateTarGzExtension(inputFilePath);
// 创建输出目录
Files.createDirectories(Paths.get(outputDirPath));
// 构建解压命令
String[] cmd = {
"/bin/bash",
"-c",
String.format("tar -xzf %s --warning=no-timestamp --no-same-owner -C %s",
Paths.get(inputFilePath).toAbsolutePath(),
Paths.get(outputDirPath).toAbsolutePath())
};
return executeCommand(cmd, "解压");
}
private static Path buildOutputPath(Path sourcePath, String outputPathStr) {
Path outputPath = Paths.get(outputPathStr).normalize();
if (Files.isDirectory(outputPath)) {
String sourceDirName = getLastNonEmptyPathPart(sourcePath);
return outputPath.resolve(sourceDirName + ".tar.gz");
}
return outputPath;
}
private static void createParentDir(Path path) throws IOException {
Path parent = path.getParent();
if (parent != null && !Files.exists(parent)) {
Files.createDirectories(parent);
logger.info("已创建父目录:{}", parent);
}
}
private static void validateTarGzExtension(String filename) {
if (!filename.toLowerCase().endsWith(".tar.gz")) {
throw new IllegalArgumentException("只支持.tar.gz格式文件");
}
}
private static String executeCommand(String[] cmd, String operation) throws IOException {
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
try {
Process process = pb.start();
StringBuilder output = new StringBuilder();
// 读取命令输出
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
}
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new IOException(operation + "失败,退出码:" + exitCode + "\n" + output);
}
logger.info("{}成功:{}", operation, output);
return operation + "成功";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException(operation + "进程被中断", e);
}
}
// 保留原有路径处理方法
private static String getLastNonEmptyPathPart(Path path) {
Path normalized = path.normalize();
int nameCount = normalized.getNameCount();
// 处理根目录特殊情况(如:/app)
if (nameCount == 0) {
String pathStr = normalized.toString();
int lastSeparator = pathStr.lastIndexOf(File.separatorChar);
return lastSeparator > 0 ? pathStr.substring(lastSeparator + 1) : pathStr;
}
return normalized.getName(nameCount - 1).toString();
}
}
java实现linux文件的解压缩(确保md5sum一致)的更多相关文章
- Java实现压缩文件与解压缩文件
由于工作需要,需要将zip的压缩文件进行解压,经过调查发现,存在两个开源的工具包,一个是Apache的ant工具包,另一个就是Java api自带的工具包:但是Java自带的工具包存在问题:如果压缩或 ...
- java ZipOutputStream压缩文件,ZipInputStream解压缩
java中实现zip的压缩与解压缩.java自带的 能实现的功能比较有限. 本程序功能:实现简单的压缩和解压缩,压缩文件夹下的所有文件(文件过滤的话需要对File进一步细节处理). 对中文的支持需要使 ...
- java修改linux文件
package vedio.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Fil ...
- Linux的压缩/解压缩文件处理 zip & unzip
Linux的压缩/解压缩命令详解及实例 压缩服务器上当前目录的内容为xxx.zip文件 zip -r xxx.zip ./* 解压zip文件到当前目录 unzip filename.zip 另:有些服 ...
- Linux下zip格式文件的解压缩和压缩
Linux下zip格式文件的解压缩和压缩 Linux下的软件包很多都是压缩包,软件的安装就是解压缩对应的压缩包.所以,就需要熟练使用常用的压缩命令和解压缩命令.最常用的压缩格式有.tar.gz/tgz ...
- linux下java调用.so文件的方法1: JNI
摘自http://blog.163.com/squall_smile/blog/static/6034984020129296931793/ https://my.oschina.net/simabe ...
- Java在linux下调用C/C++生成的so文件
1.CplusUtil.java是java web工程中的一个工具类内容如下:CplusUtil.java package cn.undoner.utils; /** * Created by ${& ...
- Java实现对zip和rar文件的解压缩
通过java实现对zip和rar文件的解压缩
- Linux文件压缩、解压缩及归档工具一
主题Linux文件压缩.解压缩及归档工具 压缩工具很重要的,因为要经常到互联网下载包 一compress/uncompress compress [-dfvcVr] [-b maxbits] [fil ...
- 利用Java进行zip文件压缩与解压缩
摘自: https://www.cnblogs.com/alphajuns/p/12442315.html 工具类: package com.alphajuns.util; import java.i ...
随机推荐
- linux ssh 免密登录
1.服务器端开启密钥登录模式 $ vim /etc/ssh/sshd_config # 是否允许 root 远程登录 PermitRootLogin yes # 密码登录是否打开 PasswordAu ...
- mac mamp php扩展安装
官网下载需要开启的php扩展 PHP扩展下载官网地址 解压扩展包,指定mamp所使用的php版本的phpize编译安装 # 在解压的扩展包中执行以下命令 /Applications/MAMP/bin/ ...
- NumPy学习5
今天学习了11, NumPy数组元素增删改查NumPy 数组元素的增删改查操作,主要有以下方法:数组元素操作方法函数名称 描述说明resize 返回指定形状的新数组.append 将元素值添加到数组的 ...
- 关于普通程序员该如何参与AI学习的三个建议以及自己的实践
大部分程序员在学习大语言模型的时候都比较痛苦,感觉AI是如此之近又如此之远,仿佛能搞明白一点,又好像什么也没明白.就像我们在很远的地方看珠穆拉玛峰,感觉它就像一个不大的山包,感觉只要自己做足准备咬咬牙 ...
- 【前端JSP思考】JSP中#{},${}和%{}的区别
JSP中#{},${}和%{}的区别: #{} #{}:对语句进行预编译,此语句解析的是占位符?,可以防止SQL注入, 比如打印出来的语句 select * from table where id=? ...
- 【Python】配置pip使用国内镜像源
配置pip使用国内镜像源 零.问题 使用pip安装插件时总是很慢,咋解决呢? 壹.解决 在桌面上你的文件夹内新建pip目录,一般路径如下:C:\Users\{$你的用户名},比如我的用户名是Minuy ...
- leetcode每日一题:最小化字符串长度
题目 2716. 最小化字符串长度 给你一个下标从 0 开始的字符串 s ,重复执行下述操作 任意 次: 在字符串中选出一个下标 i ,并使 c 为字符串下标 i 处的字符.并在 i 左侧(如果有)和 ...
- unity 多层叠加的BillBoard特效转序列帧特效降低overdraw
- 使用XML的方式编写:@Aspect运用
例子. 接口 public interface Calculator { // 加 public int add(int i, int j); // 减 public int sub(int i, i ...
- 🎀idea-java序列化serialversionUID自动生成
简介 java.io.Serializable 是 Java 中的一个标记接口(marker interface),它没有任何方法或字段.当一个类实现了 Serializable 接口,那么这个类的对 ...