From f6feaeb2cdd78d2ff8565d11b81df14692cfac52 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 23 Mar 2022 17:13:23 +0800 Subject: [PATCH] fix code --- CHANGELOG.md | 1 + .../cn/hutool/core/io/file/FileAppender.java | 70 ++++++++++++++----- .../cn/hutool/core/text/csv/CsvParser.java | 3 +- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc41ddc8e..0ba639f2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ * 【cron 】 增加CronPatternParser、MatcherTable * 【http 】 GlobalHeaders增加系统属性allowUnsafeServerCertChange、allowUnsafeRenegotiation * 【http 】 UserAgentUtil 解析,增加MiUI/XiaoMi浏览器判断逻辑(pr#581@Gitee) +* 【core 】 FileAppender添加锁构造(pr#2211@Github) ### 🐞Bug修复 * 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@Gitee) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/file/FileAppender.java b/hutool-core/src/main/java/cn/hutool/core/io/file/FileAppender.java index df1b03d78..20a97eeba 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/file/FileAppender.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/file/FileAppender.java @@ -1,6 +1,8 @@ package cn.hutool.core.io.file; +import cn.hutool.core.thread.lock.LockUtil; import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.ObjectUtil; import java.io.File; import java.io.PrintWriter; @@ -8,6 +10,7 @@ import java.io.Serializable; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.locks.Lock; /** * 文件追加器
@@ -18,22 +21,32 @@ import java.util.List; * @author looly * @since 3.1.2 */ -public class FileAppender implements Serializable{ +public class FileAppender implements Serializable { private static final long serialVersionUID = 1L; private final FileWriter writer; - /** 内存中持有的字符串数 */ + /** + * 内存中持有的字符串数 + */ private final int capacity; - /** 追加内容是否为新行 */ + /** + * 追加内容是否为新行 + */ private final boolean isNewLineMode; - /** 数据行缓存 */ + /** + * 数据行缓存 + */ private final List list; + /** + * 写出锁,用于保护写出线程安全 + */ + private final Lock lock; /** * 构造 * - * @param destFile 目标文件 - * @param capacity 当行数积累多少条时刷入到文件 + * @param destFile 目标文件 + * @param capacity 当行数积累多少条时刷入到文件 * @param isNewLineMode 追加内容是否为新行 */ public FileAppender(File destFile, int capacity, boolean isNewLineMode) { @@ -43,16 +56,30 @@ public class FileAppender implements Serializable{ /** * 构造 * - * @param destFile 目标文件 - * @param charset 编码 - * @param capacity 当行数积累多少条时刷入到文件 + * @param destFile 目标文件 + * @param charset 编码 + * @param capacity 当行数积累多少条时刷入到文件 * @param isNewLineMode 追加内容是否为新行 */ public FileAppender(File destFile, Charset charset, int capacity, boolean isNewLineMode) { + this(destFile, charset, capacity, isNewLineMode, null); + } + + /** + * 构造 + * + * @param destFile 目标文件 + * @param charset 编码 + * @param capacity 当行数积累多少条时刷入到文件 + * @param isNewLineMode 追加内容是否为新行 + * @param lock 是否加锁,添加则使用给定锁保护写出,保证线程安全,{@code null}则表示无锁 + */ + public FileAppender(File destFile, Charset charset, int capacity, boolean isNewLineMode, Lock lock) { this.capacity = capacity; this.list = new ArrayList<>(capacity); this.isNewLineMode = isNewLineMode; this.writer = FileWriter.create(destFile, charset); + this.lock = ObjectUtil.defaultIfNull(lock, LockUtil::getNoLock); } /** @@ -65,7 +92,13 @@ public class FileAppender implements Serializable{ if (list.size() >= capacity) { flush(); } - list.add(line); + + this.lock.lock(); + try{ + list.add(line); + } finally { + this.lock.unlock(); + } return this; } @@ -75,15 +108,20 @@ public class FileAppender implements Serializable{ * @return this */ public FileAppender flush() { - try(PrintWriter pw = writer.getPrintWriter(true)){ - for (String str : list) { - pw.print(str); - if (isNewLineMode) { - pw.println(); + this.lock.lock(); + try{ + try (PrintWriter pw = writer.getPrintWriter(true)) { + for (String str : list) { + pw.print(str); + if (isNewLineMode) { + pw.println(); + } } } + list.clear(); + } finally { + this.lock.unlock(); } - list.clear(); return this; } } diff --git a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java index 690127f4f..46cd9e3c1 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/csv/CsvParser.java @@ -397,7 +397,8 @@ public final class CsvParser extends ComputeIter implements Closeable, S } /** - * 读取到缓存 + * 读取到缓存
+ * 全量读取,会重置Buffer中所有数据 * * @param reader {@link Reader} */