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一致)的更多相关文章

  1. Java实现压缩文件与解压缩文件

    由于工作需要,需要将zip的压缩文件进行解压,经过调查发现,存在两个开源的工具包,一个是Apache的ant工具包,另一个就是Java api自带的工具包:但是Java自带的工具包存在问题:如果压缩或 ...

  2. java ZipOutputStream压缩文件,ZipInputStream解压缩

    java中实现zip的压缩与解压缩.java自带的 能实现的功能比较有限. 本程序功能:实现简单的压缩和解压缩,压缩文件夹下的所有文件(文件过滤的话需要对File进一步细节处理). 对中文的支持需要使 ...

  3. java修改linux文件

    package vedio.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Fil ...

  4. Linux的压缩/解压缩文件处理 zip & unzip

    Linux的压缩/解压缩命令详解及实例 压缩服务器上当前目录的内容为xxx.zip文件 zip -r xxx.zip ./* 解压zip文件到当前目录 unzip filename.zip 另:有些服 ...

  5. Linux下zip格式文件的解压缩和压缩

    Linux下zip格式文件的解压缩和压缩 Linux下的软件包很多都是压缩包,软件的安装就是解压缩对应的压缩包.所以,就需要熟练使用常用的压缩命令和解压缩命令.最常用的压缩格式有.tar.gz/tgz ...

  6. linux下java调用.so文件的方法1: JNI

    摘自http://blog.163.com/squall_smile/blog/static/6034984020129296931793/ https://my.oschina.net/simabe ...

  7. Java在linux下调用C/C++生成的so文件

    1.CplusUtil.java是java web工程中的一个工具类内容如下:CplusUtil.java package cn.undoner.utils; /** * Created by ${& ...

  8. Java实现对zip和rar文件的解压缩

    通过java实现对zip和rar文件的解压缩

  9. Linux文件压缩、解压缩及归档工具一

    主题Linux文件压缩.解压缩及归档工具 压缩工具很重要的,因为要经常到互联网下载包 一compress/uncompress compress [-dfvcVr] [-b maxbits] [fil ...

  10. 利用Java进行zip文件压缩与解压缩

    摘自: https://www.cnblogs.com/alphajuns/p/12442315.html 工具类: package com.alphajuns.util; import java.i ...

随机推荐

  1. HarmonyOS应用开发者高级认证【考题+答案】

    HarmonyOS应用开发者高级认证 前言 考试简介 掌握鸿蒙的核心概念和端云一体化开发.数据.网络.媒体.并发.分布式.多设备协同等关键技术能力,具备独立设计和开发鸿蒙应用能力. 博文说明 本博文的 ...

  2. nginx 配置go服务反向代理

    nginx 配置 详细请看Nginx 极简教程 server { listen 80; server_name localhost; #charset koi8-r; # nginx访问活动日志 ac ...

  3. postman发送数组

    postman发送数组 第一种 第二种

  4. nginx: [error] open() "/usr/local/nginx/nginx.pid" failed (2: No such file or directory)

    nginx 启动出现错误 nginx: [error] open() "/usr/local/nginx/nginx.pid" failed (2: No such file or ...

  5. deepseek内网离线部署手册

    前言 在当下 AI 浪潮汹涌的时代,DeepSeek 以其卓越的性能和出色的表现,迅速成为了众多专业人士和科技爱好者热议的焦点工具.在众多AI大模型的比拼中,DeepSeek 展现出了优越的实力.然而 ...

  6. 神经网络与模式识别课程报告-卷积神经网络(CNN)算法的应用

    ======================================================================================= 完整的神经网络与模式识别 ...

  7. 算法图解,关于数组,链表,以及大O表示法

    有关数组.链表以及大O表示法 关于数组 [1] 连续性:数组在内存中连续储存,就像是看电影的一群人排排坐. [2] 易读性:数组中的元素可以随意读取. [3] 难改性:由于连续的特性,增减元素都会导致 ...

  8. B@se-还原错误字母表转码的base64编码

    题目: 密文:MyLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbvD== JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOe ...

  9. [框架应用系列:Quartz快速上手] Java定时任务解决方案之Quartz集群

    Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵 活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度. ...

  10. 【数据结构与算法】Java链表与递归:移除链表元素

    Java链表与递归:移除链表元素 Java https://leetcode-cn.com/problems/remove-linked-list-elements/solution/javalian ...