//try()里每个声明的变量类型都必须是Closeable的子类,就一个close方法;相当于系统自动将关闭操作放到了finally里面而不需要我们自己写了
//导出
try (ServletOutputStream outputStream = response.getOutputStream();
ZipOutputStream zos = new ZipOutputStream(outputStream, StandardCharsets.UTF_8);
InputStream isM = new ByteArrayInputStream(mysqlXml.getBytes());
BufferedInputStream bufferedInputStream = new BufferedInputStream(isM, 1024 * 10)) {
response.setContentType("application/octet-stream");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String encodeName = URLEncoder.encode(System.currentTimeMillis() + ".zip", StandardCharsets.UTF_8.name());
response.setHeader("Content-Disposition", "attachment;filename=\"" + encodeName + "\"; filename*=utf-8''" + encodeName);
ZipEntry zipEntry = new ZipEntry("Mysql.xml");
zos.putNextEntry(zipEntry);
int read;
byte[] buf = new byte[1024 * 10];
read = 0;
while ((read = bufferedInputStream.read(buf, 0, 1024 * 10)) != -1) {
zos.write(buf, 0, read);
}
zos.flush();
outputStream.flush();
} catch (IOException e) {
log.info("导出失败", e);
}
//导入,用到了本地缓存(解决OOM问题)
InputStream is = null;
try {
is= file.getInputStream();
ByteBuffer byteBuffer = FileUtil.readZip(file.getInputStream(), FileUtil.Type.BUFFER);
String xmlStr = FileUtil.byteBufferToString(byteBuffer);
ImportRequest importRequest = ImportRequest.builder().inputStream(is).
uid(uid).xmlString(xmlStr).roleList(roleList).status(status).build();
exportService.importDoc(importRequest);
response.setResultMes("导入成功");
} catch (Exception e) {
response.setResultMes("导入失败" + e.getMessage() );
log.error("controller import doc error:", e);
} finally {
StreamUtil.closeStream(is);
}
@Slf4j
public class FileUtil {
private static Logger logger = LoggerFactory.getLogger(FileUtil.class);
public static final String ZIP_SUFFIX = ".zip";
public static final String XLSX = ".xlsx";
public enum Type {
XML, BUFFER
}
/**
* 获取配置文件公共方法
*
* @param fileName
* @return
*/
public static Properties getProperties(String fileName) {
Properties p = new Properties();
InputStream in = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(fileName);
if (in == null) {
return p;
}
try {
p.load(in);
} catch (IOException e) {
logger.error("-- 读取配置文件失败", e);
} finally {
try {
if(in != null) {
in.close();
}
} catch (Exception e2) {
// TODO: handle exception
}
}
return p;
}
public static byte[] getBytes(String path) {
// 构建指定文件
File file = new File(path);
InputStream in = null;
try {
// 根据文件创建文件的输入流
in = new FileInputStream(file);
// 创建字节数组
byte[] data = new byte[1024];
// 读取内容,放到字节数组里面
in.read(data);
return data;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(in!=null)
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 将字符串导出ZIP文件
* @param response 读取流
* @param contentMap key -> 文件名 ,value -> 文件内容
* @param zipName 压缩包名称
*/
public static void exportZipByResponse(HttpServletResponse response, Map<String,String> contentMap, String zipName) {
if (null == contentMap || contentMap.size() == 0) {
throw new BizException("导出内容为空");
}
if (null == zipName || !zipName.endsWith(ZIP_SUFFIX)) {
zipName = zipName + ZIP_SUFFIX;
}
ZipOutputStream zos = null;
ServletOutputStream os = null;
try {
os = response.getOutputStream();
zos = new ZipOutputStream(os, StandardCharsets.UTF_8);
response.setContentType("application/octet-stream");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String encodeName = URLEncoder.encode(zipName, StandardCharsets.UTF_8.name());
response.setHeader("Content-Disposition", "attachment;filename=\"" + encodeName + "\"; filename*=utf-8''" + encodeName);
for (Map.Entry<String,String> entry : contentMap.entrySet()) {
if (null == entry.getKey() || null == entry.getValue()) {
continue;
}
InputStream inputStream = new ByteArrayInputStream(entry.getValue().getBytes());
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream, 1024);
ZipEntry zipEntry = new ZipEntry(entry.getKey());
zos.putNextEntry(zipEntry);
byte[] buf = new byte[1024];
int read;
while ((read = bufferedInputStream.read(buf, 0, 1024)) != -1) {
zos.write(buf, 0, read);
}
zos.flush();
os.flush();
}
} catch (IOException e) {
log.info("导出Zip包失败", e);
throw new BizException("导出Zip包失败");
} finally {
StreamUtil.closeStream(zos);
StreamUtil.closeStream(os);
}
}
/**
* 读取前端传入的 MultipartFile,内容转换成String
*/
public static String readMultipartFile(MultipartFile file) {
InputStream is = null;
try {
is = file.getInputStream();
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString(StandardCharsets.UTF_8.name());
} catch (Exception e) {
log.error("读取MultipartFile失败", e);
throw new BizException("读取MultipartFile失败");
} finally {
StreamUtil.closeStream(is);
}
}
/**
* 将workbook通过response导出.xlsx文件,压缩成 .zip文件
*/
public static void exportWorkBookByResponse(String zipName, Map<String, Workbook> workbookMap, HttpServletResponse httpServletResponse){
if (null == workbookMap || workbookMap.size() == 0) {
return;
}
if (!zipName.endsWith(ZIP_SUFFIX)) {
zipName = zipName + ZIP_SUFFIX;
}
for (String workbookName : workbookMap.keySet()) {
if (!workbookName.endsWith(XLSX)) {
throw new BizException("仅支持XLSX格式");
}
}
ZipOutputStream zos = null;
ByteArrayOutputStream bos = null;
BufferedInputStream bis = null;
InputStream is = null;
try {
zipName = URLEncoder.encode(zipName, StandardCharsets.UTF_8.name());
httpServletResponse.setContentType("application/octet-stream;charset=UTF-8");
httpServletResponse.setHeader("Content-Disposition", "attachment;filename="
+ new String(zipName.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
zos = new ZipOutputStream(httpServletResponse.getOutputStream());
for (Map.Entry<String, Workbook> entry : workbookMap.entrySet()) {
Workbook workbook = entry.getValue();
bos = new ByteArrayOutputStream();
workbook.write(bos);
byte[] bytes = bos.toByteArray();
is = new ByteArrayInputStream(bytes);
bis = new BufferedInputStream(is, 1024);
ZipEntry zipEntry = new ZipEntry(entry.getKey());
zos.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int read;
while ((read = bis.read(buffer, 0, 1024)) != -1) {
zos.write(buffer, 0, read);
}
zos.flush();
bos.flush();
}
} catch (Exception e){
log.info("出现异常!", e);
} finally {
StreamUtil.closeStream(zos);
StreamUtil.closeStream(bis);
StreamUtil.closeStream(bos);
StreamUtil.closeStream(is);
}
}
/**
* 解析压缩包
*/
public static <T> Map<String, T> readZipFile(InputStream inputStream, Type type) throws IOException {
ZipInputStream zipInputStream = null;
ZipEntry zipEntry;
ByteArrayOutputStream byteArrayOutputStream;
Map<String, T> dataMap = new HashMap<>();
try {
zipInputStream = new ZipInputStream(inputStream, Charset.defaultCharset());
byteArrayOutputStream = new ByteArrayOutputStream();
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (zipEntry.isDirectory()) {
continue;
}
byte[] buffer = new byte[1024];
int len;
while ((len = zipInputStream.read(buffer)) > -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
byteArrayOutputStream.flush();
InputStream fileRead = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
T data = readZip(fileRead ,type);
dataMap.put(zipEntry.getName(), data);
byteArrayOutputStream.reset();
}
} catch (Exception e){
log.info("文件格式校验不通过,无法解压转换!", e);
throw new BizException("文件格式校验不通过,无法解压转换!");
}finally {
if (null != zipInputStream) {
zipInputStream.closeEntry();
}
StreamUtil.closeStream(zipInputStream);
StreamUtil.closeStream(inputStream);
}
return dataMap;
}
public static <T> T readZip(InputStream fileRead, Type type) {
switch (type) {
case XML:
return (T) readXml(fileRead);
case BUFFER:
return (T) readBuffer(fileRead);
default:
throw new BizException("无匹配类型: " + type.name());
}
}
/**
* 读取XML文件
*/
public static String readXml (InputStream fileRead) {
try {
int size = fileRead.available();
byte[] array = new byte[size];
fileRead.read(array);
return new String(array, Charset.defaultCharset());
} catch (Exception e) {
throw new BizException("读取压缩包(XML)文件转换为字符串出现异常");
}finally {
StreamUtil.closeStream(fileRead);
}
}
public static ByteBuffer readBuffer (InputStream fileRead) {
try {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(fileRead.available());
ReadableByteChannel channel = Channels.newChannel(fileRead);
channel.read(byteBuffer);
byteBuffer.flip();
return byteBuffer;
} catch (Exception e) {
throw new BizException("读取压缩包(XML)文件转换为字符串出现异常");
}finally {
StreamUtil.closeStream(fileRead);
}
}
public static String byteBufferToString(ByteBuffer buffer) {
try {
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
CharBuffer charBuffer = decoder.decode(buffer);
buffer.flip();
return charBuffer.toString();
} catch (CharacterCodingException e) {
throw new BizException("解析直接内存失败");
}
}
}