企业网站域名在哪申请,wordpress模板电影,网站关键词快照优化,网站运维目录 List删除满足条件的元素#xff0c;并且避免索引错误或并发修改异常常用方法使用迭代器删除元素通过逆向循环删除元素Java8 的 removeIf()方法 获取不到日志内容问题排查尝试解决最终解决 List删除满足条件的元素#xff0c;并且避免索引错误或并发修改异常常用方法
使… 目录 List删除满足条件的元素并且避免索引错误或并发修改异常常用方法使用迭代器删除元素通过逆向循环删除元素Java8 的 removeIf()方法 获取不到日志内容问题排查尝试解决最终解决 List删除满足条件的元素并且避免索引错误或并发修改异常常用方法
使用迭代器删除元素
List list new ArrayList();
list.add(A);
list.add(B);
list.add(C);
Iterator iterator list.iterator();
while (iterator.hasNext()) {String element iterator.next();if (element.equals(B)) {iterator.remove(); // 使用迭代器的 remove() 方法删除元素}
}通过逆向循环删除元素
List list new ArrayList();
list.add(A);
list.add(B);
list.add(C);
for (int i list.size() - 1; i 0; i--) {if (list.get(i).equals(B)) {list.remove(i); // 通过逆向循环删除元素}
}Java8 的 removeIf()方法
简单的使用 Lambda 表达式
List list new ArrayList();
list.add(A);
list.add(B);
list.add(C);
list.removeIf(element - element.equals(B));复杂的通过使用匿名类实现 Predicate 接口的方式
ListString list new ArrayList();
list.add(A);
list.add(B);
list.add(C);
list.add(D);
// 假如 ListTest tests则为new PredicateTest()
list.removeIf(new PredicateString() {Overridepublic boolean test(String element) {// 在这里编写复杂的逻辑来判断是否删除元素// 返回 true 表示删除该元素返回 false 表示保留该元素return element.startsWith(A) || element.endsWith(D);}
});获取不到日志内容问题排查
通过FileUtils.readFileToString()读取日志文件获取文件内容日志文件有数据但是获取不到内容可能原因
文件路径问题请确保logFile参数指定的文件路径是正确的路径并且可以访问该文件。您可以在代码中添加一些调试语句输出logFile的路径然后验证该路径是否正确。文件读取权限确保您正在以足够的权限运行代码以便能够读取指定的日志文件。如果您在一个受限制的环境中运行代码则可能需要提升您的权限或更改文件的权限设置。文件内容编码问题如果日志文件使用了特定的编码方式进行编码例如UTF-8请确保在使用FileUtils.readFileToString()时指定正确的编码方式。可以尝试使用FileUtils.readFileToString(logFile, “UTF-8”)来明确指定编码方式。文件访问冲突如果您的代码与其他程序同时访问该日志文件可能发生访问冲突或文件锁定导致无法读取文件内容。在调试期间确保没有其他程序或进程锁定或占用了该日志文件。
尝试解决
改成异步方法日志依然读取不到但是作业状态确实是完结状态日志应该已经写完了springboot异步方法配置启动类添加EnableAsync异步方法上添加Async注解判断文件写入完成后再进行读取操作依然无效而且假如中间有几秒没有写入日志但是写文件并没有结束容易误判结束
import java.io.File;public class LogFileReader {private static final int CHECK_INTERVAL_MS 1000; // 检查间隔时间单位为毫秒public static void main(String[] args) {String filePath path/to/logfile.txt; // 替换为您的日志文件路径File logFile new File(filePath);// 获取初始文件长度和修改时间long initialSize logFile.length();long lastModified logFile.lastModified();while (true) {// 等待指定时间间隔try {Thread.sleep(CHECK_INTERVAL_MS);} catch (InterruptedException e) {e.printStackTrace();}// 检查文件是否发生变化long currentSize logFile.length();long currentModified logFile.lastModified();if (currentSize initialSize currentModified lastModified) {// 文件大小和修改时间未发生变化文件写入完成String logContent FileUtils.readFileToString(logFile, UTF-8);System.out.println(logContent);break; // 退出循环}// 更新初始文件长度和修改时间initialSize currentSize;lastModified currentModified;}}}替换FileUtils.readFileToString()通过BufferedReader读取日志BufferedReader 和 FileReader 来逐行读取文件的内容。通过调用 readLine() 方法可以一次读取一行内容并将其存储到 line 变量中。然后可以对每行内容进行处理例如打印出来或进行其他操作。使用这种方式即使文件未完全写入也能读取到已经写入的部分内容。但是结果是依然读取不到。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;public class LogFileReader {public static void main(String[] args) {String filePath path/to/logfile.txt; // 替换为您的日志文件路径File logFile new File(filePath);try (BufferedReader reader new BufferedReader(new FileReader(logFile))) {String line;while ((line reader.readLine()) ! null) {// 处理每行日志内容System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}}最终解决
没有调用项目中日志处理类的end()方法导致的。对于BufferedReader来说在文件正在写入的过程中它是可以读取到已经写入部分内容的。之所以依然查看不到日志内容是因为没有调用 end() 方法来完成日志的写入操作和关闭文件流的操作可能导致读取不到已经写入的内容
写入缓冲区未刷新使用FileWriter来写入文件而FileWriter内部使用了写入缓冲区它会先将数据写入缓冲区然后根据一定条件将缓冲区的数据刷新到文件中。如果没有调用end()方法缓冲区的数据可能还未被刷新到文件中从而导致BufferedReader读取不到正确的文件内容。文件流未关闭 在调用end()方法时会关闭文件流FileWriter关闭文件流会将缓冲区的剩余数据刷新到文件中并释放系统资源。如果没有调用end()方法关闭文件流可能会导致缓冲区中的数据没有被刷新到文件中从而无法读取到正确的文件内容。
以下为日志处理类源码供参考分析
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** 日志处理器.*/
Slf4j
Component
public class LogHandler {private static MapLong, ListString logMap new HashedMap();private static MapLong, FileWriter fileWriterMap new HashMap();private static String taskLogPath;PostConstructpublic void init() {write();}PreDestroypublic void destory() {fileWriterMap.forEach((batchId, fw) - {try {fw.flush();fw.close();} catch (IOException e) {log.error(关闭流失败{}, e);}});}public static synchronized void start(Long batchId) {try {if (logMap.containsKey(batchId)) {log.info(已存在批次号{}的任务, batchId);return;}File logFile new File(getLogPath(batchId));if (logFile.exists()) {log.info(批次号{}已存在日志文件不能重复提交, batchId);return;}logFile.createNewFile();logMap.put(batchId, new ArrayListString());fileWriterMap.put(batchId, new FileWriter(logFile, true));} catch (Exception e) {log.error(批次号{}开始记录任务失败{}, batchId, e);}}/*** 记录日志.*/public static void log(Long batchId, String logContent) {if (null ! logMap.get(batchId)) {logMap.get(batchId).add(DateUtils.formatDateTime(DateUtils.now()) 批次号{ batchId } logContent);}}/*** 记录异常.*/public static void exception(Long batchId, Exception e) {if (null ! logMap.get(batchId)) {logMap.get(batchId).add(DateUtils.formatDateTime(DateUtils.now()) Throwables.getStackTraceAsString(e));}}/*** 日志记录到文件中.*/private static void write() {Thread logWriteThread new Thread(new Runnable() {Overridepublic void run() {while (true) {logMap.forEach((batchId, logContentList) - {if (CollectionUtils.isEmpty(logContentList)) {return;}try {FileWriter fw fileWriterMap.get(batchId);if (null ! fw) {writeLog2File(fw, logContentList, true);logContentList.clear();}} catch (Exception e) {log.error(批次号为{}的日志写入文件报错{}, batchId, e);}});sleep(15);}}});logWriteThread.start();}/*** 该batchId的日志记录结束.*/public static synchronized void end(Long batchId) {if (!fileWriterMap.containsKey(batchId)) {log.info(批次号为{}的输出流不存在, batchId);return;}FileWriter fw fileWriterMap.get(batchId);try {ListString logContentList logMap.get(batchId);if (CollectionUtils.isNotEmpty(logContentList)) {try {writeLog2File(fw, logContentList, true);logContentList null;} catch (Exception e) {log.error(批次号为{}的日志写入文件报错{}, batchId, e);}}logMap.remove(batchId);fileWriterMap.remove(batchId);} finally {try {fw.close();} catch (IOException e) {log.error(关闭流错误{}, e);}}}private static void writeLog2File(FileWriter fw, ListString logContentList, boolean flush) throws Exception {for (String logContent : logContentList) {fw.write(logContent);fw.write(\r\n);}if (flush) {fw.flush();}}public static String getLogPath(Long batchId) {return taskLogPath batchId .log;}private static void sleep(long timeOut) {try {Thread.sleep(timeOut * 1000);} catch (InterruptedException e) {log.error(sleep error{}, e);}}Value(${log_path})public void setTaskLogPath(String taskLogPath) {LogHandler.taskLogPath taskLogPath;}}