From e546ad92d968ac3707fe40d14fac712b1fa3f17c Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 28 Oct 2019 10:00:42 +0800 Subject: [PATCH] add io close --- CHANGELOG.md | 1 + .../main/java/cn/hutool/core/io/IoUtil.java | 47 ++++++++++++------- .../cn/hutool/core/io/file/FileReader.java | 2 +- .../java/cn/hutool/core/util/ZipUtil.java | 40 +++++++--------- 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6de17ac4d..486d2107f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### 新特性 * 【setting】 增加System.getenv变量替换支持 * 【core】 XmlUtil中mapToStr支持namespace(pr#599@Github) +* 【core】 ZipUtil修改策略:默认关闭输入流(issue#604@Github) ### Bug修复 * 【core】 解决ConcurrentHashSet不能序列化的问题(issue#600@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java index 00dcfd77e..64660fbdc 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java @@ -64,7 +64,7 @@ public class IoUtil { // -------------------------------------------------------------------------------------- Copy start /** - * 将Reader中的内容复制到Writer中 使用默认缓存大小 + * 将Reader中的内容复制到Writer中 使用默认缓存大小,拷贝后不关闭Reader * * @param reader Reader * @param writer Writer @@ -76,7 +76,7 @@ public class IoUtil { } /** - * 将Reader中的内容复制到Writer中 + * 将Reader中的内容复制到Writer中,拷贝后不关闭Reader * * @param reader Reader * @param writer Writer @@ -89,7 +89,7 @@ public class IoUtil { } /** - * 将Reader中的内容复制到Writer中 + * 将Reader中的内容复制到Writer中,拷贝后不关闭Reader * * @param reader Reader * @param writer Writer @@ -124,7 +124,7 @@ public class IoUtil { } /** - * 拷贝流,使用默认Buffer大小 + * 拷贝流,使用默认Buffer大小,拷贝后不关闭流 * * @param in 输入流 * @param out 输出流 @@ -136,7 +136,7 @@ public class IoUtil { } /** - * 拷贝流 + * 拷贝流,拷贝后不关闭流 * * @param in 输入流 * @param out 输出流 @@ -149,7 +149,7 @@ public class IoUtil { } /** - * 拷贝流 + * 拷贝流,拷贝后不关闭流 * * @param in 输入流 * @param out 输出流 @@ -215,13 +215,17 @@ public class IoUtil { Assert.notNull(in, "FileInputStream is null!"); Assert.notNull(out, "FileOutputStream is null!"); - final FileChannel inChannel = in.getChannel(); - final FileChannel outChannel = out.getChannel(); - + FileChannel inChannel = null; + FileChannel outChannel = null; try { + inChannel = in.getChannel(); + outChannel = out.getChannel(); return inChannel.transferTo(0, inChannel.size(), outChannel); } catch (IOException e) { throw new IORuntimeException(e); + } finally { + close(outChannel); + close(inChannel); } } @@ -514,15 +518,31 @@ public class IoUtil { } /** - * 从流中读取bytes + * 从流中读取bytes,读取完毕后关闭流 * * @param in {@link InputStream} * @return bytes * @throws IORuntimeException IO异常 */ public static byte[] readBytes(InputStream in) throws IORuntimeException { + return readBytes(in, true); + } + + /** + * 从流中读取bytes + * + * @param in {@link InputStream} + * @param isCloseStream 是否关闭输入流 + * @return bytes + * @throws IORuntimeException IO异常 + * @since 5.0.4 + */ + public static byte[] readBytes(InputStream in, boolean isCloseStream) throws IORuntimeException { final FastByteArrayOutputStream out = new FastByteArrayOutputStream(); copy(in, out); + if(isCloseStream){ + close(in); + } return out.toByteArray(); } @@ -670,12 +690,7 @@ public class IoUtil { * @throws IORuntimeException IO异常 */ public static > T readLines(Reader reader, final T collection) throws IORuntimeException { - readLines(reader, new LineHandler() { - @Override - public void handle(String line) { - collection.add(line); - } - }); + readLines(reader, (LineHandler) collection::add); return collection; } diff --git a/hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java b/hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java index f63cbf6a7..b0a684241 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java @@ -196,7 +196,7 @@ public class FileReader extends FileWrapper { * @throws IORuntimeException IO异常 */ public List readLines() throws IORuntimeException { - return readLines(new ArrayList()); + return readLines(new ArrayList<>()); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java index 5128d5e75..df0351032 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java @@ -244,11 +244,11 @@ public class ZipUtil { } /** - * 对流中的数据加入到压缩文件
+ * 对流中的数据加入到压缩文件 * * @param zipFile 生成的Zip文件,包括文件名。注意:zipPath不能是srcPath路径下的子文件夹 * @param path 流数据在压缩文件中的路径或文件名 - * @param in 要压缩的源 + * @param in 要压缩的源,默认关闭 * @param charset 编码 * @return 压缩文件 * @throws UtilException IO异常 @@ -279,7 +279,7 @@ public class ZipUtil { * * @param zipFile 生成的Zip文件,包括文件名。注意:zipPath不能是srcPath路径下的子文件夹 * @param paths 流数据在压缩文件中的路径或文件名 - * @param ins 要压缩的源 + * @param ins 要压缩的源,添加完成后自动关闭流 * @param charset 编码 * @return 压缩文件 * @throws UtilException IO异常 @@ -425,8 +425,8 @@ public class ZipUtil { public static File unzip(ZipFile zipFile, File outFile) throws IORuntimeException { try { final Enumeration em = (Enumeration) zipFile.entries(); - ZipEntry zipEntry = null; - File outItemFile = null; + ZipEntry zipEntry; + File outItemFile; while (em.hasMoreElements()) { zipEntry = em.nextElement(); // FileUtil.file会检查slip漏洞,漏洞说明见http://blog.nsfocus.net/zip-slip-2/ @@ -475,8 +475,8 @@ public class ZipUtil { */ public static File unzip(ZipInputStream zipStream, File outFile) throws UtilException { try { - ZipEntry zipEntry = null; - File outItemFile = null; + ZipEntry zipEntry; + File outItemFile; while (null != (zipEntry = zipStream.getNextEntry())) { // FileUtil.file会检查slip漏洞,漏洞说明见http://blog.nsfocus.net/zip-slip-2/ outItemFile = FileUtil.file(outFile, zipEntry.getName()); @@ -548,12 +548,10 @@ public class ZipUtil { try { zipFileObj = new ZipFile(zipFile, charset); final Enumeration em = (Enumeration) zipFileObj.entries(); - ZipEntry zipEntry = null; + ZipEntry zipEntry; while (em.hasMoreElements()) { zipEntry = em.nextElement(); - if (zipEntry.isDirectory()) { - continue; - } else if (name.equals(zipEntry.getName())) { + if ((false == zipEntry.isDirectory()) && name.equals(zipEntry.getName())) { return IoUtil.readBytes(zipFileObj.getInputStream(zipEntry)); } } @@ -687,7 +685,7 @@ public class ZipUtil { */ public static byte[] unGzip(InputStream in, int length) throws UtilException { GZIPInputStream gzi = null; - FastByteArrayOutputStream bos = null; + FastByteArrayOutputStream bos; try { gzi = (in instanceof GZIPInputStream) ? (GZIPInputStream) in : new GZIPInputStream(in); bos = new FastByteArrayOutputStream(length); @@ -865,13 +863,12 @@ public class ZipUtil { /** * 获得 {@link ZipOutputStream} * - * @param zipFile 压缩文件 + * @param out 压缩文件流 * @param charset 编码 * @return {@link ZipOutputStream} */ private static ZipOutputStream getZipOutputStream(OutputStream out, Charset charset) { - charset = (null == charset) ? DEFAULT_CHARSET : charset; - return new ZipOutputStream(out, charset); + return new ZipOutputStream(out, ObjectUtil.defaultIfNull(charset, DEFAULT_CHARSET)); } /** @@ -916,17 +913,11 @@ public class ZipUtil { * @since 4.0.5 */ private static void addFile(File file, String path, ZipOutputStream out) throws UtilException { - BufferedInputStream in = null; - try { - in = FileUtil.getInputStream(file); - addFile(in, path, out); - } finally { - IoUtil.close(in); - } + addFile(FileUtil.getInputStream(file), path, out); } /** - * 添加文件流到压缩包,不关闭输入流 + * 添加文件流到压缩包,添加后关闭流 * * @param in 需要压缩的输入流 * @param path 压缩的路径 @@ -943,6 +934,7 @@ public class ZipUtil { } catch (IOException e) { throw new UtilException(e); } finally { + IoUtil.close(in); closeEntry(out); } } @@ -969,7 +961,7 @@ public class ZipUtil { * 判断压缩文件保存的路径是否为源文件路径的子文件夹,如果是,则抛出异常(防止无限递归压缩的发生) * * @param zipFile 压缩后的产生的文件路径 - * @param srcFile 被压缩的文件或目录 + * @param srcFiles 被压缩的文件或目录 */ private static void validateFiles(File zipFile, File... srcFiles) throws UtilException { if (zipFile.isDirectory()) {