This commit is contained in:
Looly 2022-03-23 17:13:23 +08:00
parent d1122bd3c5
commit f6feaeb2cd
3 changed files with 57 additions and 17 deletions

View File

@ -39,6 +39,7 @@
* 【cron 】 增加CronPatternParser、MatcherTable * 【cron 】 增加CronPatternParser、MatcherTable
* 【http 】 GlobalHeaders增加系统属性allowUnsafeServerCertChange、allowUnsafeRenegotiation * 【http 】 GlobalHeaders增加系统属性allowUnsafeServerCertChange、allowUnsafeRenegotiation
* 【http 】 UserAgentUtil 解析增加MiUI/XiaoMi浏览器判断逻辑pr#581@Gitee * 【http 】 UserAgentUtil 解析增加MiUI/XiaoMi浏览器判断逻辑pr#581@Gitee
* 【core 】 FileAppender添加锁构造pr#2211@Github
### 🐞Bug修复 ### 🐞Bug修复
* 【core 】 修复ObjectUtil.hasNull传入null返回true的问题pr#555@Gitee * 【core 】 修复ObjectUtil.hasNull传入null返回true的问题pr#555@Gitee

View File

@ -1,6 +1,8 @@
package cn.hutool.core.io.file; package cn.hutool.core.io.file;
import cn.hutool.core.thread.lock.LockUtil;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import java.io.File; import java.io.File;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -8,6 +10,7 @@ import java.io.Serializable;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.locks.Lock;
/** /**
* 文件追加器<br> * 文件追加器<br>
@ -18,22 +21,32 @@ import java.util.List;
* @author looly * @author looly
* @since 3.1.2 * @since 3.1.2
*/ */
public class FileAppender implements Serializable{ public class FileAppender implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final FileWriter writer; private final FileWriter writer;
/** 内存中持有的字符串数 */ /**
* 内存中持有的字符串数
*/
private final int capacity; private final int capacity;
/** 追加内容是否为新行 */ /**
* 追加内容是否为新行
*/
private final boolean isNewLineMode; private final boolean isNewLineMode;
/** 数据行缓存 */ /**
* 数据行缓存
*/
private final List<String> list; private final List<String> list;
/**
* 写出锁用于保护写出线程安全
*/
private final Lock lock;
/** /**
* 构造 * 构造
* *
* @param destFile 目标文件 * @param destFile 目标文件
* @param capacity 当行数积累多少条时刷入到文件 * @param capacity 当行数积累多少条时刷入到文件
* @param isNewLineMode 追加内容是否为新行 * @param isNewLineMode 追加内容是否为新行
*/ */
public FileAppender(File destFile, int capacity, boolean isNewLineMode) { public FileAppender(File destFile, int capacity, boolean isNewLineMode) {
@ -43,16 +56,30 @@ public class FileAppender implements Serializable{
/** /**
* 构造 * 构造
* *
* @param destFile 目标文件 * @param destFile 目标文件
* @param charset 编码 * @param charset 编码
* @param capacity 当行数积累多少条时刷入到文件 * @param capacity 当行数积累多少条时刷入到文件
* @param isNewLineMode 追加内容是否为新行 * @param isNewLineMode 追加内容是否为新行
*/ */
public FileAppender(File destFile, Charset charset, int capacity, boolean 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.capacity = capacity;
this.list = new ArrayList<>(capacity); this.list = new ArrayList<>(capacity);
this.isNewLineMode = isNewLineMode; this.isNewLineMode = isNewLineMode;
this.writer = FileWriter.create(destFile, charset); 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) { if (list.size() >= capacity) {
flush(); flush();
} }
list.add(line);
this.lock.lock();
try{
list.add(line);
} finally {
this.lock.unlock();
}
return this; return this;
} }
@ -75,15 +108,20 @@ public class FileAppender implements Serializable{
* @return this * @return this
*/ */
public FileAppender flush() { public FileAppender flush() {
try(PrintWriter pw = writer.getPrintWriter(true)){ this.lock.lock();
for (String str : list) { try{
pw.print(str); try (PrintWriter pw = writer.getPrintWriter(true)) {
if (isNewLineMode) { for (String str : list) {
pw.println(); pw.print(str);
if (isNewLineMode) {
pw.println();
}
} }
} }
list.clear();
} finally {
this.lock.unlock();
} }
list.clear();
return this; return this;
} }
} }

View File

@ -397,7 +397,8 @@ public final class CsvParser extends ComputeIter<CsvRow> implements Closeable, S
} }
/** /**
* 读取到缓存 * 读取到缓存<br>
* 全量读取会重置Buffer中所有数据
* *
* @param reader {@link Reader} * @param reader {@link Reader}
*/ */