包含文件压缩, 解压, 字节数据输出流转base64
package com.vxdata.activity.utils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@Slf4j
public class ZipUtils {
// 要压缩的文件格式
public static final String FORMAT = "zip";
/**
* 文件上传常量 分隔符
*/
public static final String FILE_UPLOAD_SEPARATOR = "/";
/**
* 文件上传常量 点
*/
public static final String FILE_UPLOAD_POINT = ".";
/**
* 对外提供的压缩文件方法
* @param path 要压缩的文件的全路径
* @throws IOException 异常信息
* 缺陷: 文件夹如果是空文件夹, 不会加入压缩文件中
*/
public static void zipLocal(String path, String outputPath) throws IOException {
zipFileTree(new File(path), FORMAT, outputPath);
}
/**
*
* @param zipFilePath 要解压的文件的全路径
* @param desDirectory 解压后的存储位置的,不用加文件名
* @throws Exception 异常信息
*/
public static void unZipLocal(String zipFilePath, String desDirectory) throws Exception {
unzip(zipFilePath, desDirectory);
}
/**
* 压缩文件或文件夹(包括所有子目录文件)
*
* @param sourceFile 源文件
* @param format 格式(zip或rar)
* @throws IOException 异常信息
*/
private static void zipFileTree(File sourceFile, String format, String outputPath) throws IOException {
ZipOutputStream zipOutputStream = null;
try {
String zipFileName;
if (sourceFile.isDirectory()) {
// 文件夹
zipFileName = outputPath + File.separator + sourceFile.getName() + "."
+ format;
} else { // 单个文件
zipFileName = outputPath
+ sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf("."))
+ "." + format;
}
// 压缩输出流
zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
// 递归压缩内部文件
zip(sourceFile, zipOutputStream, "");
} finally {
if (null != zipOutputStream) {
// 关闭流
try {
zipOutputStream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
/**
* 递归压缩内部文件
*
* @param file 当前文件
* @param zipOutputStream 压缩输出流
* @param relativePath 相对路径
* @throws IOException IO异常
*/
private static void zip(File file, ZipOutputStream zipOutputStream, String relativePath)
throws IOException {
FileInputStream fileInputStream = null;
try {
// 当前为文件夹
if (file.isDirectory()) {
// 当前文件夹下的所有文件
File[] list = file.listFiles();
if (null != list) {
// 计算当前的相对路径
relativePath += (relativePath.length() == 0 ? "" : File.separator) + file.getName();
// 递归压缩每个文件
for (File f : list) {
zip(f, zipOutputStream, relativePath);
}
}
} else { // 压缩文件
// 计算文件的相对路径
relativePath += (relativePath.length() == 0 ? "" : File.separator) + file.getName();
// 写入单个文件
zipOutputStream.putNextEntry(new ZipEntry(relativePath));
fileInputStream = new FileInputStream(file);
int readLen;
byte[] buffer = new byte[1024];
while ((readLen = fileInputStream.read(buffer)) != -1) {
zipOutputStream.write(buffer, 0, readLen);
}
zipOutputStream.closeEntry();
}
} finally {
// 关闭流
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
/**
* 解压路径
*
* @param zipFilePath 待解压文件
* @param desDirectory 解压到的目录
* @throws Exception
*/
public static void unzip(String zipFilePath, String desDirectory) throws Exception {
unzipByFile(new File(zipFilePath), desDirectory);
}
/**
* 解压File
* @param zipFile
* @param desDirectory
* @throws Exception
*/
public static void unzipByFile(File zipFile, String desDirectory) throws Exception{
File desDir = new File(desDirectory);
if (!desDir.exists()) {
boolean mkdirSuccess = desDir.mkdir();
if (!mkdirSuccess) {
throw new Exception("创建解压目标文件夹失败");
}
}
// 读入流
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile));
// 遍历每一个文件
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
if (zipEntry.isDirectory()) {
// 文件夹
String unzipFilePath = desDirectory + File.separator + zipEntry.getName();
// 直接创建
mkdir(new File(unzipFilePath));
} else { // 文件
String unzipFilePath = desDirectory + File.separator + zipEntry.getName();
File file = new File(unzipFilePath);
// 创建父目录
mkdir(file.getParentFile());
// 写出文件流
BufferedOutputStream bufferedOutputStream =
new BufferedOutputStream(new FileOutputStream(unzipFilePath));
byte[] bytes = new byte[1024];
int readLen;
while ((readLen = zipInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, readLen);
}
bufferedOutputStream.close();
}
zipInputStream.closeEntry();
zipEntry = zipInputStream.getNextEntry();
}
zipInputStream.close();
}
/**
* 如果父目录不存在则创建
* @param file
*/
private static void mkdir(File file) {
if (null == file || file.exists()) {
return;
}
mkdir(file.getParentFile());
file.mkdir();
}
/**
* Zip文件数据转成Map对象
* @param file 文件
* @return Map对象
*/
public static Map<String, Object> readZip2Map(File file) throws Exception {
Map<String, Object> map = new HashMap<>();
Map<String, String> photos = new LinkedHashMap<>();
try(InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (zipEntry.isDirectory()) {
continue;
}
if ("txt".equals(getSuffixName(zipEntry.getName()))) {
StringBuilder sb = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(zipInputStream));
try {
String line = null;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
JSONObject json = JSONObject.parseObject(sb.toString());
map.put("json", json);
}catch (Exception e){
e.printStackTrace();
}
} else {
String name = getFileName(zipEntry.getName());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedInputStream bis = new BufferedInputStream(zipInputStream);
try {
int size;
byte[] bytes = new byte[1024 * 4];
while ((size = bis.read(bytes, 0, bytes.length)) > 0) {
baos.write(bytes, 0, size);
}
baos.flush();
String base64 = asBase64(baos);
/*map.put(String.valueOf(index),base64);
index++;*/
photos.put(name,base64);
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(baos!=null){
baos.close();
}
}catch (Exception e){}
}
}
}
if(photos.size()>0){
map.put("photos", photos);
}
zipInputStream.closeEntry();
}catch (Exception e){
e.printStackTrace();
}
return map;
}
/**
* 文件名获取后缀
* @param fileName 文件名
* @return
*/
private static String getSuffixName(String fileName) {
String suffix = null;
String originalFilename = fileName;
if (StringUtils.isNotBlank(fileName)) {
if (fileName.contains(FILE_UPLOAD_SEPARATOR)) {
fileName = fileName.substring(fileName.lastIndexOf(FILE_UPLOAD_SEPARATOR) + 1);
}
if (fileName.contains(FILE_UPLOAD_POINT)) {
suffix = fileName.substring(fileName.lastIndexOf(FILE_UPLOAD_POINT) + 1);
} else {
if (log.isErrorEnabled()) {
log.error("filename error without suffix : {}", originalFilename);
}
}
}
return suffix;
}
private static String getFileName(String path) {
int index = path.lastIndexOf("/");
if(index==-1)
{
return path;
}else {
return path.substring(index+1);
}
}
/**
* 字节数据输出流转base64
* @param baos 字节数据输出流对象
* @return base64字符串
*/
private static String asBase64(ByteArrayOutputStream baos) {
//BASE64Encoder encoder = new BASE64Encoder();
byte[] data = baos.toByteArray();
return Base64.getEncoder().encodeToString(data);
}
}
提供前端下载文件
/**
* 提供前端下载压缩包
*
* @param response
* @param zipFileName 文件全路径
*/
public void downloadZip(HttpServletResponse response, String zipFileName) {
// zipName为上一步文件打包zip时传入的zipName
File zipFile = new File(zipFileName);
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition", "attachment; filename=" + zipFile.getName());
FileInputStream fileInputStream = null;
OutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
fileInputStream = new FileInputStream(zipFile);
byte[] bufs = new byte[1024 * 10];
int read = 0;
while ((read = fileInputStream.read(bufs, 0, 1024 * 10)) != -1) {
outputStream.write(bufs, 0, read);
}
fileInputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 删除压缩包
File file = new File(zipFileName);
file.delete();
if (fileInputStream != null) {
fileInputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
将InputStream写入本地文件
/**
* 将InputStream写入本地文件
*
* @param destination 写入本地文件的全路径, **/**/**.jpg 或 **/**.txt等
* @param input 输入流
* @throws IOException
*/
public static void writeToLocal(String destination, InputStream input)
throws IOException {
int len = -1;
byte[] bytes = new byte[1024 * 4];
try (FileOutputStream fos = new FileOutputStream(destination)) {
while ((len = input.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
fos.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
把多个文件打包生压缩包传给前端
可以是文件夹, 但是文件夹里面如果包含文件夹,只会压缩最里层文件夹
package com.vxdata.activity.utils;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class DownloadZipUtil {
/**
* 把文件打成压缩包并输出到客户端浏览器中
*
* @param response 客户端响应
* @param srcFiles 所有要压缩的文件的路径
* @param zipFileName 压缩包的名称
*/
public static void downloadZipFiles(HttpServletResponse response, List<String> srcFiles, String zipFileName) {
try {
response.reset(); // 重点突出
response.setCharacterEncoding("UTF-8");
response.setContentType("application/zip");
// 对文件名进行编码处理中文问题
zipFileName = new String(zipFileName.getBytes(), StandardCharsets.UTF_8);
response.setHeader("Content-Disposition", "attachment;filename=" + zipFileName);
// --设置成这样可以不用保存在本地,再输出, 通过response流输出,直接输出到客户端浏览器中。
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
zipFile(srcFiles, zos);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 递归压缩文件
*
* @param filePaths 需要压缩的文件路径集合
* @throws IOException
*/
private static void zipFile(List<String> filePaths, ZipOutputStream zos) {
//设置读取数据缓存大小
byte[] buffer = new byte[4096];
try {
//循环读取文件路径集合,获取每一个文件的路径
for (String filePath : filePaths) {
File inputFile = new File(filePath);
//判断文件是否存在
if (inputFile.exists()) {
//判断是否属于文件,还是文件夹
if (inputFile.isFile()) {
//创建输入流读取文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(inputFile));
//将文件写入zip内,即将文件进行打包
zos.putNextEntry(new ZipEntry(inputFile.getName()));
//写入文件的方法,同上
int size = 0;
//设置读取数据缓存大小
while ((size = bis.read(buffer)) > 0) {
zos.write(buffer, 0, size);
}
//关闭输入输出流
zos.closeEntry();
bis.close();
} else { //如果是文件夹,则使用穷举的方法获取文件,写入zip
File[] files = inputFile.listFiles();
List<String> filePathsTem = new ArrayList<String>();
for (File fileTem : files) {
filePathsTem.add(fileTem.toString());
}
zipFile(filePathsTem, zos);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != zos) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}