java操作zip压缩文件加密码和解密工具类
<!-- zip压缩文件工具类 -->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
package com.topnetwork.util;
import java.io.*;
import com.jcraft.jsch.*;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* ftp上传下载工具类
*/
public class SFtpUtil {
/**
* 利用JSch包实现SFTP上传文件
*
* @param ip 主机IP
* @param user 主机登陆用户名
* @param psw 主机登陆密码
* @param port 主机ssh2登陆端口,如果取默认值,传-1
* ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:
* put(): 文件上传
* get(): 文件下载
* cd(): 进入指定目录
* ls(): 得到指定目录下的文件列表
* rename(): 重命名指定文件或目录
* rm(): 删除指定文件
* mkdir(): 创建目录
* rmdir(): 删除目录
*/
public static void sshSftpUpload(String ip, String user, String psw, int port, String localDirFileName, String destDir, String fileName) {
try {
Session session = null;
Channel channel = null;
JSch jsch = new JSch();
if (port <= 0) {
//连接服务器,采用默认端口
session = jsch.getSession(user, ip);
} else {
//采用指定的端口连接服务器
session = jsch.getSession(user, ip, port);
}
//如果服务器连接不上,则抛出异常
if (session == null) {
throw new Exception("session is null");
}
//设置登陆主机的密码
session.setPassword(psw);//设置密码
//设置第一次登陆的时候提示,可选值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
//设置登陆超时时间
session.connect(30000);
try {
//创建sftp通信通道
channel = (Channel) session.openChannel("sftp");
channel.connect(1000);
ChannelSftp sftp = (ChannelSftp) channel;
// Class cl = ChannelSftp.class;
// Field f =cl.getDeclaredField("server_version");
// f.setAccessible(true);
// f.set(sftp, 2);
// 乱码问题实际上是使用的xftp软件的乱码,使用xshell查看之后并无乱码
// 相当于执行命令 cd /tmp
// 进入服务器指定的文件夹
// sftp.cd(destDir);
// 进入临时目录文件夹
sftp.cd("/ftp/temp");
// 以下代码实现从本地上传一个文件到服务器
String uncode = UUID.randomUUID().toString().replace("-", "").toLowerCase();
String temp_fileName = uncode + "." + (fileName.split("\\.")[1]);
OutputStream outstream = sftp.put(temp_fileName);
InputStream instream = new FileInputStream(new File(localDirFileName));
byte b[] = new byte[1024];
int n;
while ((n = instream.read(b)) != -1) {
outstream.write(b, 0, n);
}
// 传输完成 将文件转移到正式目录
copyFile(session, "/ftp/temp/" + temp_fileName, "/ftp/real/" + fileName);
// 将临时文件中的数据删除
sftp.rm(temp_fileName);
outstream.flush();
outstream.close();
instream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
session.disconnect();
channel.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void copyFile(Session session, String sourceFile, String destinationFile) {
try {
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("cp " + sourceFile + " " + destinationFile);
channel.connect();
while (channel.isConnected()) {
Thread.sleep(20);
}
int status = channel.getExitStatus();
if (status != 0)
System.out.println("copy failed, exit status is " + status);
} catch (Exception e) {
System.out.println("copy failed");
}
}
/**
* 利用JSch包实现SFTP下载文件
*
* @param ip 主机IP
* @param user 主机登陆用户名
* @param psw 主机登陆密码
* @param port 主机ssh2登陆端口,如果取默认值,传-1
* ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:
* put(): 文件上传
* get(): 文件下载
* cd(): 进入指定目录
* ls(): 得到指定目录下的文件列表
* rename(): 重命名指定文件或目录
* rm(): 删除指定文件
* mkdir(): 创建目录
* rmdir(): 删除目录
*/
public static String sshSftpDownload(String ip, String user, String psw, int port, String localDirFileName, String destDir) {
try {
Session session = null;
Channel channel = null;
JSch jsch = new JSch();
if (port <= 0) {
//连接服务器,采用默认端口
session = jsch.getSession(user, ip);
} else {
//采用指定的端口连接服务器
session = jsch.getSession(user, ip, port);
}
//如果服务器连接不上,则抛出异常
if (session == null) {
throw new Exception("session is null");
}
//设置登陆主机的密码
session.setPassword(psw);//设置密码
//设置第一次登陆的时候提示,可选值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
//设置登陆超时时间
session.connect(30000);
try {
//创建sftp通信通道
channel = (Channel) session.openChannel("sftp");
channel.connect(1000);
ChannelSftp sftp = (ChannelSftp) channel;
//相当于执行命令 cd /tmp
//进入服务器指定的文件夹
sftp.cd(destDir);
//列出服务器指定的文件列表
Vector v = sftp.ls("*");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dirName = sdf.format(new Date());
localDirFileName = localDirFileName + "/" + dirName;
for (int i = 0; i < v.size(); i++) {
String detailMsg = v.get(i).toString();
String[] allMsg = detailMsg.split(" ");
String file = allMsg[allMsg.length - 1];
// 当文件存在的时候在进行下载操作
InputStream inputStream = sftp.get(file);
File newFile = new File(localDirFileName);
if (!newFile.exists()) {//如果文件夹不存在
newFile.mkdir();//创建文件夹
}
FileOutputStream fileOutputStream = new FileOutputStream(new File(localDirFileName + "/" + file));
byte b[] = new byte[1024];
int n;
while ((n = inputStream.read(b)) != -1) {
fileOutputStream.write(b, 0, n);
}
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
// sftp.cd(destDir);
//2022年1月20日11:15:07 每天都会产生新的唯一的以日期命名的文件夹不在需要移动原有文件
// copyFile(session, destDir + "/" + file, "/ftp/history_file/" + file);
// sftp.rm(fileName);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
session.disconnect();
channel.disconnect();
return localDirFileName;
}
} catch (Exception e) {
e.printStackTrace();
}
return localDirFileName;
}
/**
* 删除文件 用来删除临时文件
*
* @param file
*/
public static void deleteTempFile(File file) {
file.delete();
}
}
// 带密码加密
// ZipUtil.zipFile("C:\\Users\\Administrator\\Desktop\\xin\\2022-01-20","C:\\Users\\Administrator\\Desktop\\xin\\2022-01-20.zip","admin123");
// 带密码解密
ZipUtil.unZipFile(localDirFilePath,"admin123");
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
/**
* danyu
* 压缩文件工具类
*/
public class ZipUtil {
private static final Logger log = LoggerFactory.getLogger(ZipUtil.class);
/**
*
* 压缩指定路径的文件
* @param srcFilePath 待压缩文件路径
* @param zipPathFileName zip文件全路径名
* @param password 加密密码
* @return
*/
public static boolean zipFile(String srcFilePath, String zipPathFileName, String password){
try {
// 生成的压缩文件
ZipFile zipFile = new ZipFile(zipPathFileName);
ZipParameters parameters = new ZipParameters();
// 压缩级别
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if(!StringUtils.isEmpty(password)){
parameters.setEncryptFiles(true);
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
parameters.setPassword(password);
}
// 要打包的文件夹
File currentFile = new File(srcFilePath);
File[] fs = currentFile.listFiles();
// 遍历test文件夹下所有的文件、文件夹
for (File f : fs) {
if (f.isDirectory()) {
zipFile.addFolder(f.getPath(), parameters);
} else {
zipFile.addFile(f, parameters);
}
}
return true;
} catch (ZipException e) {
e.printStackTrace();
log.error("压缩文件【"+srcFilePath+"】到路径【"+zipPathFileName+"】失败:\n"+e.getMessage());
return false;
}
}
/**
* @param zipFileFullName zip文件所在的路径名
* @param password 需要解压的密码
* @return
*/
public static HashSet<String> unZipFile(String zipFileFullName, String password) {
HashSet<String> filePathSet = new HashSet<>();
// 获取当前文件夹下的所有已经解压的文件
File newFile = new File(zipFileFullName);
String[] newList = newFile.list();
Map<String, String> zippedMap = new HashMap<>();
for (String file_name : newList) {
if(!file_name.contains(".zip")){
String key = zipFileFullName + File.separator +file_name+".zip";
zippedMap.put(key,file_name);
}
}
try {
List<String> fileNames = new ArrayList<>();
findFileList(new File(zipFileFullName),fileNames);
for (String fileName : fileNames) {
ZipFile zipFile = new ZipFile(fileName);
if(zippedMap.containsKey(fileName)){
continue;
}
// 如果解压需要密码
if(StringUtils.isNotEmpty(password)&&zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
String[] split = {};
if(File.separator.equals("/")){
split = fileName.split("/");
}
if(File.separator.equals("\\")){
split = fileName.split("\\\\");
}
String filePathName = split[split.length-1];
String filePath = filePathName.replace(".zip","");
String newPath = zipFileFullName + File.separator + filePath;
filePathSet.add(newPath);
zipFile.extractAll(newPath);
}
return filePathSet;
} catch (ZipException e) {
e.printStackTrace();
return filePathSet;
}
}
/**
* 读取目录下的所有文件
*
* @param dir
* 目录
* @param fileNames
* 保存文件名的集合
* @return
*/
public static void findFileList(File dir, List<String> fileNames) {
if (!dir.exists() || !dir.isDirectory()) {// 判断是否存在目录
return;
}
String[] files = dir.list();// 读取目录下的所有目录文件信息
for (int i = 0; i < files.length; i++) {// 循环,添加文件名或回调自身
File file = new File(dir, files[i]);
if (file.isFile()) {// 如果文件
String name = file.getName();
if(name.startsWith("password-backup")) {
fileNames.add(dir + File.separator + file.getName());// 添加文件全路径名
}
if(name.startsWith("sc-done")){
fileNames.add(dir + File.separator + file.getName());// 添加文件全路径名
}
} else {// 如果是目录
findFileList(file, fileNames);// 回调自身继续查询
}
}
}
/**
* 添加文件到压缩文件中
* @param zipFullFileName zip文件所在路径及全名
* @param fullFileNameList 待添加的文件全路径集合
* @param rootFolderInZip 在压缩文件里的文件夹名
* @return
*/
public static boolean addFilesToZip(String zipFullFileName, List<String> fullFileNameList, String rootFolderInZip) {
try {
ZipFile zipFile = new ZipFile(zipFullFileName);
ArrayList<File> addFiles = new ArrayList<>();
for (String fileName:fullFileNameList) {
addFiles.add(new File(fileName));
}
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if(StringUtils.isNotEmpty(rootFolderInZip)){
if(rootFolderInZip.endsWith("/")==false){
rootFolderInZip = rootFolderInZip+"/";
}
parameters.setRootFolderInZip(rootFolderInZip);
}
zipFile.addFiles(addFiles, parameters);
return true;
} catch (ZipException e) {
e.printStackTrace();
log.error("添加文件失败:\n"+e.getMessage());
return false;
}
}
/**
* 从压缩文件中删除路径
* @param zipFullFileName
* @param fileName
* @return
*/
public static boolean deleteFileInZip(String zipFullFileName, String fileName) {
try {
ZipFile zipFile = new ZipFile(zipFullFileName);
zipFile.removeFile(fileName);
return true;
} catch (ZipException e) {
e.printStackTrace();
log.error("删除文件失败:\n"+e.getMessage());
return false;
}
}
}