java - 项目启动时自动将jar包名称、路径、进程号信息写入指定的文件里
1.需要配置启动时记录项目进程号到指定公共文件里
参考我的随笔 java - sprootboot 配置启动时记录进程号 - 岑惜 - 博客园 (cnblogs.com)
2. 指定公共文件路径
3.对springboot 生命周期做监听
在 生命周期 ApplicationReadyEvent 里处理
完整代码

import cn.cenxi.common.basic.StringUtils; import cn.cenxi.common.file.FileFormat; import com.google.common.base.Joiner; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.event.ApplicationFailedEvent; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.system.ApplicationHome; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextStartedEvent; import org.springframework.stereotype.Component; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * springboot 生命周期 */ @Component @Slf4j public class ApplicationEventListener implements ApplicationListener<ApplicationEvent> { // 记录当前jar进程号文件的路径 @Value("${spring.pid.file}") private String filePath; // 公共的jar包进程数据文件路径 @Value("${configFile.AllProPidrec}") private String AllProPidrecPath; // jar包名称 @Value("${spring.application.name}") private String applicationName; @SneakyThrows @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof ApplicationReadyEvent) { if (StringUtils.isEmpty(filePath) || StringUtils.isEmpty(AllProPidrecPath)) return; File file = new File(filePath); if (!file.exists()) { log.error("pidRec.txt文件不存在:路径在:" + filePath); } //进程号 String pid = FileFormat.getTxtForUtf8(file, filePath); //启动jar文件路径 ApplicationHome h = new ApplicationHome(getClass()); File jarF = h.getSource(); String jarPath = jarF.getParentFile().toString(); // log.error(jarPath); //写入指定位置 File allProPidrec = new File(AllProPidrecPath); String allProPidrecTxt = ""; if (allProPidrec.exists()) { allProPidrecTxt = FileFormat.getTxtForUtf8(allProPidrec, AllProPidrecPath); } else { allProPidrec.createNewFile(); } List<String> list = Arrays.asList(allProPidrecTxt.split("\n")); List<String> resList = new ArrayList<>(); for (String str : list) { if (StringUtils.isEmpty(str)) { continue; } String[] arr = str.split("&"); if (!StringUtils.equals(arr[0] + "&" + arr[1], applicationName + "&" + jarPath)) { resList.add(str); } } resList.add(applicationName + "&" + jarPath + "&" + pid ); String txt = Joiner.on("\n").join(resList); //写入文件中[覆盖写入] FileFormat.setTxt(txt, allProPidrec, AllProPidrecPath, false); } } }
相应的文件解析工具

import cn.cenxi.common.basic.StringUtils; import cn.cenxi.common.exception.ExcBox; import lombok.extern.slf4j.Slf4j; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.apache.poi.hslf.extractor.PowerPointExtractor; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XSLFSlide; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xwpf.extractor.XWPFWordExtractor; import org.apache.poi.xwpf.usermodel.IBodyElement; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.jodconverter.DocumentConverter; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import javax.annotation.Resource; import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.text.NumberFormat; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @Slf4j public class FileFormat { /** * 多次读取文件数据--解决utf-8中文乱码问题 */ public static String getTxtForUtf8(File file, String url) { try { if (null == file) { file = new File(url); } if (!file.exists()) return null; //字节输入流 //意思是文件内容向JVM输入 FileInputStream fis = new FileInputStream(file); StringBuilder txt = new StringBuilder(); //============================================== //开启管道 FileChannel fc = fis.getChannel(); //如果设置太小的,会乱码【解决方式不靠谱】 //如果是utf-8,最大长度是4字节 ,GBK 为2 byte //因此这里设置最小是4 ByteBuffer buffer = ByteBuffer.allocate(6); //管道将文件对象的内容读出并放入缓冲区里面,字符上限为上面缓冲区设置的最大值 //read()方法返回的是个抽象的整数,意为字符的长度/个数,当为空时返回-1 int mread; //此时管道读取数据放入缓冲,缓冲的定位position 不再是0 ,需要将limit设为position,而position需要恢复到0 , //形成 【 limit == 当前的position值【也等于mread】,position == 0 , cap 不变】 while ((mread = fc.read(buffer)) != -1) { byte b; //计算出此时中文utf-8的编码长度后放入这里 int idx; //out可以bai改成任何不与保留关键字相同的字符,其中du标签out代表了这个for循环结构zhi体。理论上,标签可以标记任何结构体 //break out ;代表语句执行跳出整个for循环结构 out: for (idx = buffer.position() - 1; idx >= 0; idx--) { b = buffer.get(idx); if ((b & 0xff) >> 7 == 0) { // 0xxxxxxx break; } if ((b & 0xff & 0xc0) == 0xc0) { // 11xxxxxx,110xxxxx、1110xxxx、11110xxx idx -= 1; break; } if ((b & 0xff & 0x80) == 0x80) { for (int i = 1; i < 4; i++) { b = buffer.get(idx - i); if ((b & 0xff & 0xc0) == 0xc0) { if ((b & 0xff) >> (5 + 1 - i) == 0xf >> (3 - i)) { //break out ;代表语句执行跳出整个for循环结构 break out; } else { idx = idx - 1 - i; //break out ;代表语句执行跳出整个for循环结构 break out; } } } } } //缓冲区定位参数移位 buffer.flip(); //获取限制数,备份 int limit = buffer.limit(); //设限制数为上面计算出的utf-8字符的长度 buffer.limit(idx + 1); // 阻止读取跨界数据 //文本信息 txt.append(StandardCharsets.UTF_8.decode(buffer)); // 恢复limit buffer.limit(limit); //compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。 // limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。 //也就是说把已经写入缓冲区但是还没有读的数据左移到开头,然后将position设为该数据默认 //然后继续做写操作,不会覆盖这些数据 buffer.compact(); } //清除缓冲区 buffer.clear(); //关闭管道 fc.close(); //关闭字节输入流 fis.close(); return txt.toString(); } catch (IOException e) { ExcBox.getExcMsg(e); return null; } } /** * 把字符串写入文件[使用 buffer.put] */ public static void setTxt(String txt, File file, String url, boolean isAppen) { try { FileOutputStream fos = null; if (null != file) { fos = new FileOutputStream(file, isAppen); } if (StringUtils.isNotEmpty(url)) { fos = new FileOutputStream(url, isAppen); } //============================================== //true表示追加,如果文件存在 向里面继续添加内容,不加默认是覆盖 // FileOutputStream fos=new FileOutputStream(file,true); //获取通道,该通道允许写操作【根据字节流是输入还是输出决定是读通道还是写通道】 FileChannel fc = fos.getChannel(); //allocate是使用JVM的的内存的,适合小文件;allocateDirect则是使用系统的内存的,适合大文件 //设置字节缓的大小 ByteBuffer buffer = ByteBuffer.allocate(1024); //控制台写入字符串 // Scanner sca = new Scanner(System.in); // String str = sca.next(); //将字符串转成字节后,放入字节缓冲 buffer.put(txt.getBytes(StandardCharsets.UTF_8)); // 此行语句一定要有,每次执行了这一句才可以做io操作 buffer.flip(); //通道对字节缓冲区里的内容写入文件对象里面 fc.write(buffer); //清空缓冲块 buffer.clear(); //关闭管道 fc.close(); //关闭字节输出流 fos.close(); } catch (IOException e) { ExcBox.getExcMsg(e); } } }
本文来自博客园,作者:岑惜,转载请注明原文链接:https://www.cnblogs.com/c2g5201314/p/16543050.html
响应开源精神相互学习,内容良币驱除劣币
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!