This commit is contained in:
yuejiajun 2025-09-30 10:59:04 +08:00
parent e82e2ef66f
commit 03d7f90b9d
2 changed files with 697 additions and 0 deletions

View File

@ -0,0 +1,315 @@
package com.example.demo.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* 文件操作工具类
* 提供文件读写复制删除等通用功能
*
* @author 岳佳君 (2025年09月26日 13:48:12)
* @version 1.0.0
*/
public class FileUtil {
private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
/**
* 读取文件内容
*
* @param filePath 文件路径
* @return 文件内容
* @throws IOException IO异常
*/
public static String readFileContent(String filePath) throws IOException {
return new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
}
/**
* 写入内容到文件
*
* @param filePath 文件路径
* @param content 文件内容
* @throws IOException IO异常
*/
public static void writeFileContent(String filePath, String content) throws IOException {
// 确保父目录存在
Path path = Paths.get(filePath);
Path parentDir = path.getParent();
if (parentDir != null) {
Files.createDirectories(parentDir);
}
// 写入文件
Files.write(path, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
/**
* 追加内容到文件
*
* @param filePath 文件路径
* @param content 文件内容
* @throws IOException IO异常
*/
public static void appendFileContent(String filePath, String content) throws IOException {
// 确保父目录存在
Path path = Paths.get(filePath);
Path parentDir = path.getParent();
if (parentDir != null) {
Files.createDirectories(parentDir);
}
// 追加文件
Files.write(path, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
/**
* 复制文件
*
* @param sourceFilePath 源文件路径
* @param targetFilePath 目标文件路径
* @throws IOException IO异常
*/
public static void copyFile(String sourceFilePath, String targetFilePath) throws IOException {
Path sourcePath = Paths.get(sourceFilePath);
Path targetPath = Paths.get(targetFilePath);
// 确保目标目录存在
Path targetDir = targetPath.getParent();
if (targetDir != null) {
Files.createDirectories(targetDir);
}
// 复制文件
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
/**
* 移动文件
*
* @param sourceFilePath 源文件路径
* @param targetFilePath 目标文件路径
* @throws IOException IO异常
*/
public static void moveFile(String sourceFilePath, String targetFilePath) throws IOException {
Path sourcePath = Paths.get(sourceFilePath);
Path targetPath = Paths.get(targetFilePath);
// 确保目标目录存在
Path targetDir = targetPath.getParent();
if (targetDir != null) {
Files.createDirectories(targetDir);
}
// 移动文件
Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
/**
* 删除文件
*
* @param filePath 文件路径
* @return 是否删除成功
* @throws IOException IO异常
*/
public static boolean deleteFile(String filePath) throws IOException {
return Files.deleteIfExists(Paths.get(filePath));
}
/**
* 创建目录
*
* @param dirPath 目录路径
* @return 是否创建成功
* @throws IOException IO异常
*/
public static boolean createDirectory(String dirPath) throws IOException {
Path path = Paths.get(dirPath);
if (Files.exists(path)) {
return Files.isDirectory(path);
}
Files.createDirectories(path);
return true;
}
/**
* 删除目录包括目录下的所有文件
*
* @param dirPath 目录路径
* @return 是否删除成功
* @throws IOException IO异常
*/
public static boolean deleteDirectory(String dirPath) throws IOException {
Path path = Paths.get(dirPath);
if (!Files.exists(path)) {
return true;
}
// 递归删除目录内容
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
return true;
}
/**
* 获取文件大小
*
* @param filePath 文件路径
* @return 文件大小字节
* @throws IOException IO异常
*/
public static long getFileSize(String filePath) throws IOException {
return Files.size(Paths.get(filePath));
}
/**
* 获取文件扩展名
*
* @param fileName 文件名
* @return 文件扩展名小写
*/
public static String getFileExtension(String fileName) {
if (fileName == null || fileName.lastIndexOf('.') == -1) {
return "";
}
return fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
}
/**
* 生成唯一文件名
*
* @param originalFileName 原始文件名
* @return 唯一文件名
*/
public static String generateUniqueFileName(String originalFileName) {
String extension = getFileExtension(originalFileName);
String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
String uuid = UUID.randomUUID().toString().replaceAll("-|", "");
if (extension.isEmpty()) {
return timestamp + "_" + uuid;
} else {
return timestamp + "_" + uuid + "." + extension;
}
}
/**
* 列出目录下的所有文件
*
* @param dirPath 目录路径
* @return 文件路径列表
* @throws IOException IO异常
*/
public static List<String> listFiles(String dirPath) throws IOException {
List<String> filePaths = new ArrayList<>();
Path path = Paths.get(dirPath);
if (Files.exists(path) && Files.isDirectory(path)) {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
filePaths.add(file.toString());
return FileVisitResult.CONTINUE;
}
});
}
return filePaths;
}
/**
* 获取文件的MIME类型
*
* @param filePath 文件路径
* @return MIME类型
* @throws IOException IO异常
*/
public static String getMimeType(String filePath) throws IOException {
return Files.probeContentType(Paths.get(filePath));
}
/**
* 检查文件是否存在
*
* @param filePath 文件路径
* @return 是否存在
*/
public static boolean fileExists(String filePath) {
return Files.exists(Paths.get(filePath));
}
/**
* 清理临时文件
*
* @param dirPath 临时目录路径
* @param daysAgo 清理多少天前的文件
* @return 清理的文件数量
* @throws IOException IO异常
*/
public static int cleanTempFiles(String dirPath, int daysAgo) throws IOException {
final int[] deletedCount = {0};
Path path = Paths.get(dirPath);
if (!Files.exists(path) || !Files.isDirectory(path)) {
return deletedCount[0];
}
long cutoffTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(daysAgo);
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
try {
// 检查文件的最后修改时间
if (Files.getLastModifiedTime(file).toMillis() < cutoffTime) {
Files.delete(file);
deletedCount[0]++;
}
} catch (IOException e) {
logger.error("删除临时文件失败: {}", file, e);
}
return FileVisitResult.CONTINUE;
}
});
return deletedCount[0];
}
/**
* 创建临时文件
*
* @param prefix 文件前缀
* @param suffix 文件后缀
* @param tempDir 临时目录
* @return 临时文件路径
* @throws IOException IO异常
*/
public static String createTempFile(String prefix, String suffix, String tempDir) throws IOException {
// 确保临时目录存在
createDirectory(tempDir);
// 创建临时文件
File tempFile = File.createTempFile(prefix, suffix, new File(tempDir));
return tempFile.getAbsolutePath();
}
}

View File

@ -0,0 +1,382 @@
package com.example.demo.common.utils;
import cn.hutool.core.util.StrUtil;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
/**
* XML解析工具类
* 提供XML文件解析和转换为TXT文件的核心功能
*
* @author 岳佳君 (2025年09月24日 23:09:02)
* @version 1.0.0
*/
public class XmlParserUtil {
/**
* 解析XML文件并转换为TXT文件
*
* @param xmlFilePath XML文件路径
* @param txtFilePath TXT文件路径
* @throws Exception 解析过程中的异常
*/
public static void parseXmlToTxt(String xmlFilePath, String txtFilePath) throws Exception {
// 读取XML文件并解析
Document document = parseXmlFile(xmlFilePath);
// 创建TXT文件
createTxtFile(document, txtFilePath);
}
/**
* 解析XML文件为Document对象
*
* @param xmlFilePath XML文件路径
* @return Document对象
* @throws Exception 解析异常
*/
public static Document parseXmlFile(String xmlFilePath) throws Exception {
// 确保文件存在
File file = new File(xmlFilePath);
if (!file.exists()) {
throw new FileNotFoundException("XML文件不存在: " + xmlFilePath);
}
// 创建DocumentBuilder并解析文件
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setIgnoringElementContentWhitespace(true);
try (FileInputStream fis = new FileInputStream(file)) {
InputSource is = new InputSource(new InputStreamReader(fis, StandardCharsets.UTF_8));
return factory.newDocumentBuilder().parse(is);
}
}
/**
* 将Document对象转换为TXT文件
*
* @param document XML文档对象
* @param txtFilePath TXT文件路径
* @throws IOException IO异常
*/
public static void createTxtFile(Document document, String txtFilePath) throws IOException {
// 确保输出目录存在
Path outputPath = Paths.get(txtFilePath).getParent();
if (outputPath != null && !Files.exists(outputPath)) {
Files.createDirectories(outputPath);
}
// 写入TXT文件
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(txtFilePath), StandardCharsets.UTF_8)) {
// 处理根元素
Element rootElement = document.getDocumentElement();
processElement(rootElement, writer, 0);
}
}
/**
* 递归处理XML元素并写入TXT文件
* 将中文XML标签转换为特定的TXT格式
*
* @param element 当前XML元素
* @param writer 输出写入器
* @param indentLevel 缩进级别
* @throws IOException IO异常
*/
private static void processElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
String tagName = element.getTagName();
String indent = " ".repeat(Math.max(0, indentLevel));
// 根据中文标签名映射到对应的TXT格式
switch (tagName) {
case "任务":
processTaskElement(element, writer, indentLevel);
break;
case "任务信息":
processTaskInfoElement(element, writer, indentLevel);
break;
case "平台":
processPlatformElement(element, writer, indentLevel);
break;
case "行动":
processActionElement(element, writer, indentLevel);
break;
default:
processGenericElement(element, writer, indentLevel);
break;
}
}
/**
* 处理任务元素
*/
private static void processTaskElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
String indent = " ".repeat(Math.max(0, indentLevel));
// 获取任务行动信息
String taskAction = getElementTextByTagName(element, "任务行动信息");
if (StrUtil.isNotBlank(taskAction)) {
writer.write(indent + "task " + taskAction + " # 任务信息");
writer.newLine();
}
// 处理子元素
processChildElements(element, writer, indentLevel + 1);
writer.write(indent + "end_task");
writer.newLine();
}
/**
* 处理任务信息元素
*/
private static void processTaskInfoElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
String indent = " ".repeat(Math.max(0, indentLevel));
// 处理指令有效期拆分为开始和结束时间
String instructionPeriod = getElementTextByTagName(element, "指令有效期");
if (StrUtil.isNotBlank(instructionPeriod)) {
String[] timeRange = instructionPeriod.split("~");
if (timeRange.length == 2) {
writer.write(indent + "start_time " + timeRange[0].trim());
writer.newLine();
writer.write(indent + "end_time " + timeRange[1].trim());
writer.newLine();
}
}
// 处理其他子元素
processChildElements(element, writer, indentLevel);
}
/**
* 处理平台元素
*/
private static void processPlatformElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
String indent = " ".repeat(Math.max(0, indentLevel));
writer.write(indent + "platform # 平台信息");
writer.newLine();
// 处理平台子元素
String platformName = getElementTextByTagName(element, "平台名称");
String machineType = getElementTextByTagName(element, "机型");
String numOfCpus = getElementTextByTagName(element, "架数");
String platformId = getElementTextByTagName(element, "平台识别码");
String country = getElementTextByTagName(element, "国家");
if (StrUtil.isNotBlank(platformName)) {
writer.write(indent + " platform_name " + platformName);
writer.newLine();
}
if (StrUtil.isNotBlank(machineType)) {
writer.write(indent + " machine_type " + machineType);
writer.newLine();
}
if (StrUtil.isNotBlank(numOfCpus)) {
writer.write(indent + " num_of_cpus " + numOfCpus);
writer.newLine();
}
if (StrUtil.isNotBlank(platformId)) {
writer.write(indent + " platform_id " + platformId);
writer.newLine();
}
if (StrUtil.isNotBlank(country)) {
writer.write(indent + " country " + country);
writer.newLine();
}
// 处理行动子元素
processChildElements(element, writer, indentLevel + 1);
writer.write(indent + "end_platform");
writer.newLine();
}
/**
* 处理行动元素
*/
private static void processActionElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
String indent = " ".repeat(Math.max(0, indentLevel));
writer.write(indent + "action");
writer.newLine();
// 处理行动属性
if (element.hasAttributes()) {
NamedNodeMap attributes = element.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Attr attr = (Attr) attributes.item(i);
if ("label".equals(attr.getName())) {
writer.write(indent + " action_name " + attr.getValue());
writer.newLine();
}
}
}
// 处理航线名称
String routeName = getElementTextByTagName(element, "航线名称");
if (StrUtil.isNotBlank(routeName)) {
writer.write(indent + " route_name " + routeName);
writer.newLine();
}
writer.write(indent + "end_action");
writer.newLine();
}
/**
* 处理通用元素
*/
private static void processGenericElement(Element element, BufferedWriter writer, int indentLevel) throws IOException {
String tagName = element.getTagName();
String indent = " ".repeat(Math.max(0, indentLevel));
// 将中文标签名转换为英文简单映射
String englishTag = convertChineseTagToEnglish(tagName);
if (StrUtil.isNotBlank(englishTag)) {
String textContent = getElementText(element);
if (StrUtil.isNotBlank(textContent)) {
writer.write(indent + englishTag + " " + textContent);
writer.newLine();
}
}
}
/**
* 处理子元素
*/
private static void processChildElements(Element parent, BufferedWriter writer, int indentLevel) throws IOException {
NodeList children = parent.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i) instanceof Element) {
processElement((Element) children.item(i), writer, indentLevel);
}
}
}
/**
* 根据标签名获取元素文本内容
*/
private static String getElementTextByTagName(Element parent, String tagName) {
NodeList elements = parent.getElementsByTagName(tagName);
if (elements.getLength() > 0) {
Element element = (Element) elements.item(0);
return getElementText(element);
}
return "";
}
/**
* 将中文标签转换为英文标签
*/
private static String convertChineseTagToEnglish(String chineseTag) {
// 简单的中文到英文映射
switch (chineseTag) {
case "指令确认信息": return "confirm_info";
case "覆盖的指令文档": return "document_version";
default: return chineseTag;
}
}
/**
* 从XML字符串解析为Document对象
*
* @param xmlContent XML字符串内容
* @return Document对象
* @throws Exception 解析异常
*/
public static Document parseXmlString(String xmlContent) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try (InputStream inputStream = new ByteArrayInputStream(xmlContent.getBytes(StandardCharsets.UTF_8))) {
InputSource is = new InputSource(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
return factory.newDocumentBuilder().parse(is);
}
}
/**
* 获取XML元素的文本内容
*
* @param element XML元素
* @return 文本内容
*/
public static String getElementText(Element element) {
if (element == null) {
return "";
}
NodeList childNodes = element.getChildNodes();
StringBuilder textContent = new StringBuilder();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node.getNodeType() == Node.TEXT_NODE) {
textContent.append(node.getNodeValue());
}
}
return textContent.toString().trim();
}
/**
* 获取指定路径的XML元素
*
* @param document XML文档对象
* @param xpath 元素路径
* @return 元素列表
*/
public static List<Element> getElementsByPath(Document document, String xpath) {
List<Element> elements = new ArrayList<>();
// 简单实现XPath功能实际项目中可使用JAXB或XPath API
String[] pathParts = xpath.split("/");
if (pathParts.length == 0) {
return elements;
}
// 查找根元素
Element currentElement = document.getDocumentElement();
if (!currentElement.getTagName().equals(pathParts[0])) {
return elements;
}
// 递归查找子元素
for (int i = 1; i < pathParts.length; i++) {
currentElement = findChildElement(currentElement, pathParts[i]);
if (currentElement == null) {
return elements;
}
}
elements.add(currentElement);
return elements;
}
/**
* 在父元素中查找指定名称的子元素
*
* @param parent 父元素
* @param tagName 子元素标签名
* @return 子元素
*/
private static Element findChildElement(Element parent, String tagName) {
NodeList childNodes = parent.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals(tagName)) {
return (Element) node;
}
}
return null;
}
}