配置工具类加载函数优化
This commit is contained in:
@@ -31,7 +31,9 @@ public class Main {
|
||||
private static int httpPort;
|
||||
// 核心状态:volatile保证多线程可见性,false=运行,true=退出
|
||||
private static volatile boolean isExit = false;
|
||||
|
||||
// 新增:固定安卓兜底根目录
|
||||
public static final String DEFAULT_ROOT = "/sdcard/WinBoLLStudio/Sources/AuthCenterConsoleApp";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 1. 初始化退出状态为false,表示程序正常运行
|
||||
isExit = false;
|
||||
|
||||
@@ -24,9 +24,12 @@ import java.util.logging.Level;
|
||||
* 适配 Java7 语言规范与 Android API30 运行环境
|
||||
* 自动执行控制台指令测试用例,生成结构化测试报告
|
||||
* 核心优化:从config.ini读取配置,动态初始化测试路径与参数,兜底根目录固定为安卓存储路径
|
||||
* 调整:邮件测试用例改为调用 EmailSendUtils.test() 函数,利用自动初始化特性
|
||||
* 新增:loadExternalConfig配置加载成功后输出提示信息
|
||||
* 修复:移除重复配置加载,消除矛盾日志输出
|
||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2026/01/20 10:00:00
|
||||
* @LastEditTime 2026/01/21 16:00:00
|
||||
* @LastEditTime 2026/01/21 19:00:00
|
||||
*/
|
||||
public class ConsoleCmdAutoTest {
|
||||
// ========== 静态常量(配置键名+兜底根目录,不可变) ==========
|
||||
@@ -36,8 +39,6 @@ public class ConsoleCmdAutoTest {
|
||||
private static final String CONFIG_KEY_TEST_REPORT_DIR = "test_report_dir";
|
||||
private static final String CONFIG_SECTION_GLOBAL = "GlobalConfig";
|
||||
private static final String CONFIG_SECTION_TEST = "TestConfig";
|
||||
// 新增:固定安卓兜底根目录
|
||||
private static final String ANDROID_DEFAULT_ROOT = "/sdcard/WinBoLLStudio/Sources/AuthCenterConsoleApp";
|
||||
|
||||
// ========== 动态配置属性(从INI读取,可变) ==========
|
||||
private static String PROJECT_ROOT_DIR;
|
||||
@@ -94,6 +95,7 @@ public class ConsoleCmdAutoTest {
|
||||
/**
|
||||
* 从启动参数读取config.ini路径,无参数则使用当前目录下的config.ini
|
||||
* 启动参数格式:-config:xxx/config.ini
|
||||
* 新增:配置加载成功后输出日志与控制台提示
|
||||
*/
|
||||
private static void loadExternalConfig(String[] args) {
|
||||
LogUtils.d(TAG, "【函数调用】loadExternalConfig(),加载外部配置文件");
|
||||
@@ -116,10 +118,14 @@ public class ConsoleCmdAutoTest {
|
||||
// 加载配置文件,读取核心路径参数
|
||||
try {
|
||||
IniConfigUtils.loadConfig(CONFIG_FILE_PATH);
|
||||
// ========== 配置加载成功提示 ==========
|
||||
LogUtils.i(TAG, "【配置加载成功】已成功读取配置文件:" + CONFIG_FILE_PATH);
|
||||
System.out.println("✅ 配置文件加载成功:" + CONFIG_FILE_PATH);
|
||||
|
||||
// 读取项目根目录(必填),配置缺失时使用固定安卓兜底路径
|
||||
PROJECT_ROOT_DIR = IniConfigUtils.getConfigValue(CONFIG_SECTION_GLOBAL, CONFIG_KEY_ROOT_DIR);
|
||||
if (PROJECT_ROOT_DIR == null || PROJECT_ROOT_DIR.trim().isEmpty()) {
|
||||
PROJECT_ROOT_DIR = ANDROID_DEFAULT_ROOT;
|
||||
PROJECT_ROOT_DIR = Main.DEFAULT_ROOT;
|
||||
LogUtils.w(TAG, "【配置缺失】未找到PROJECT_ROOT_DIR,使用安卓兜底根目录:" + PROJECT_ROOT_DIR);
|
||||
}
|
||||
PROJECT_ROOT_DIR = PROJECT_ROOT_DIR.trim();
|
||||
@@ -140,8 +146,9 @@ public class ConsoleCmdAutoTest {
|
||||
LogUtils.i(TAG, "【路径初始化】报告目录:" + REPORT_DIR_PATH);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "【函数异常】加载外部配置失败,使用安卓兜底路径", e);
|
||||
System.err.println("❌ 配置文件加载失败:" + CONFIG_FILE_PATH + ",使用兜底路径");
|
||||
// 配置加载失败时,强制使用固定安卓兜底路径
|
||||
PROJECT_ROOT_DIR = ANDROID_DEFAULT_ROOT;
|
||||
PROJECT_ROOT_DIR = Main.DEFAULT_ROOT;
|
||||
LOG_DIR_PATH = PROJECT_ROOT_DIR + File.separator + "logs";
|
||||
REPORT_DIR_PATH = PROJECT_ROOT_DIR + File.separator + "reports";
|
||||
REPORT_FILE = REPORT_DIR_PATH + File.separator + "test-report.txt";
|
||||
@@ -152,6 +159,7 @@ public class ConsoleCmdAutoTest {
|
||||
|
||||
/**
|
||||
* 初始化测试环境:基于INI配置动态创建目录、初始化依赖工具类
|
||||
* 修复:移除重复的配置文件加载逻辑
|
||||
*/
|
||||
private static void initTestEnv() {
|
||||
LogUtils.d(TAG, "【函数调用】initTestEnv()");
|
||||
@@ -183,9 +191,10 @@ public class ConsoleCmdAutoTest {
|
||||
MainUtils.parseArgs(mockArgs);
|
||||
LogUtils.d(TAG, "【参数信息】模拟启动参数:" + MainUtils.arrayToString(mockArgs));
|
||||
|
||||
// 4. 确认加载指定路径的配置文件(双重保障)
|
||||
IniConfigUtils.loadConfig(CONFIG_FILE_PATH);
|
||||
LogUtils.d(TAG, "【配置加载】已加载指定配置文件:" + CONFIG_FILE_PATH);
|
||||
// ========== 移除重复的配置加载代码 ==========
|
||||
// 4. 确认加载指定路径的配置文件(双重保障)- 已删除,避免重复加载
|
||||
// IniConfigUtils.loadConfig(CONFIG_FILE_PATH);
|
||||
// LogUtils.d(TAG, "【配置加载】已加载指定配置文件:" + CONFIG_FILE_PATH);
|
||||
|
||||
// 5. 设置日志级别与日志输出目录
|
||||
LogUtils.setGlobalLogLevel(Level.INFO);
|
||||
@@ -194,8 +203,7 @@ public class ConsoleCmdAutoTest {
|
||||
// 6. 初始化核心工具类
|
||||
EnvInfoUtils.printEnvReport(true);
|
||||
ServerUtils.initServerUrl(MainUtils.getFinalServerUrl());
|
||||
EmailSendUtils.initEmailConfig();
|
||||
|
||||
// 移除手动初始化 EmailSendUtils,改为由 test() 函数自动处理
|
||||
System.out.println("✅ 测试环境初始化完成");
|
||||
LogUtils.d(TAG, "【函数结束】initTestEnv(),初始化成功");
|
||||
} catch (Exception e) {
|
||||
@@ -207,6 +215,7 @@ public class ConsoleCmdAutoTest {
|
||||
/**
|
||||
* 注册所有控制台指令测试用例
|
||||
* 核心调整:exit指令测试用例移至最后注册,保证最后执行
|
||||
* 关键修改:邮件测试用例改为调用 EmailSendUtils.test() 函数
|
||||
* 【Java7 兼容改造】移除 Lambda 表达式,替换为匿名内部类
|
||||
*/
|
||||
private static void registerTestCases() {
|
||||
@@ -232,7 +241,7 @@ public class ConsoleCmdAutoTest {
|
||||
}
|
||||
));
|
||||
|
||||
// 用例2:selftestmail指令测试
|
||||
// 用例2:selftestmail指令测试 - 核心修改:调用 EmailSendUtils.test() 函数
|
||||
testCaseList.add(new TestCase(
|
||||
"selftestmail指令测试",
|
||||
"验证邮件自测指令能否正常执行(需正确配置INI)",
|
||||
@@ -240,16 +249,17 @@ public class ConsoleCmdAutoTest {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
boolean initResult = EmailSendUtils.initEmailConfig();
|
||||
if (!initResult) {
|
||||
testCaseList.get(1).failReason = "邮件配置初始化失败,请检查INI文件[EmailConfig]";
|
||||
LogUtils.w(TAG, "【用例结果】selftestmail指令测试失败:" + testCaseList.get(1).failReason);
|
||||
return;
|
||||
}
|
||||
// 生成随机测试码
|
||||
String testCode = String.valueOf((int) (Math.random() * 900000 + 100000));
|
||||
EmailSendUtils.sendSelfTestEmail(testCode);
|
||||
testCaseList.get(1).isPass = true;
|
||||
LogUtils.d(TAG, "【用例结果】selftestmail指令测试通过,测试码:" + testCode);
|
||||
// 直接调用test函数,自动检查并初始化邮件配置
|
||||
boolean testResult = EmailSendUtils.test(testCode);
|
||||
if (testResult) {
|
||||
testCaseList.get(1).isPass = true;
|
||||
LogUtils.d(TAG, "【用例结果】selftestmail指令测试通过,测试码:" + testCode);
|
||||
} else {
|
||||
testCaseList.get(1).failReason = "邮件自测失败,请检查INI配置或邮箱授权码";
|
||||
LogUtils.w(TAG, "【用例结果】selftestmail指令测试失败:" + testCaseList.get(1).failReason);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
testCaseList.get(1).failReason = "邮件自测异常:" + e.getMessage();
|
||||
LogUtils.w(TAG, "【用例结果】selftestmail指令测试异常:" + testCaseList.get(1).failReason);
|
||||
|
||||
@@ -13,9 +13,10 @@ import javax.mail.internet.MimeMessage;
|
||||
/**
|
||||
* 邮件发送工具类,读取INI配置,专注验证码发送场景,兼容Android/JVM
|
||||
* 适配javax.mail依赖,原生兼容Java7语法与Android API30环境
|
||||
* 调整:配置读取改为带默认值重载方法 + 新增test()单元测试入口
|
||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2026-01-15 00:00:00
|
||||
* @LastEditTime 2026-01-17 23:00:00
|
||||
* @LastEditTime 2026-01-21 14:00:00
|
||||
*/
|
||||
public class EmailSendUtils {
|
||||
private static final String TAG = "EmailSendUtils";
|
||||
@@ -26,36 +27,37 @@ public class EmailSendUtils {
|
||||
private static String emailSubjectPrefix;
|
||||
private static String verifyCodeContentTemplate;
|
||||
|
||||
// ========== 新增:默认配置常量(配置缺失时兜底) ==========
|
||||
private static final String DEFAULT_SMTP_HOST = "smtp.qq.com";
|
||||
private static final String DEFAULT_SMTP_PORT = "587";
|
||||
private static final String DEFAULT_SUBJECT_PREFIX = "【AuthCenter 认证中心】";
|
||||
private static final String DEFAULT_CONTENT_TEMPLATE = "您的认证验证码为:{code},有效期5分钟,请及时使用,请勿泄露给他人!";
|
||||
|
||||
/**
|
||||
* 初始化邮件配置(增强校验+双键名兼容+修复Java7内部类变量final问题)
|
||||
* 调整:配置读取改为带默认值的重载方法,解决[EmailConfig]小节缺失问题
|
||||
* @return 配置完整且初始化成功返回true,否则false
|
||||
*/
|
||||
public static boolean initEmailConfig() {
|
||||
LogUtils.d(TAG, "initEmailConfig 函数调用,开始初始化邮件配置");
|
||||
String smtpHost = IniConfigUtils.getConfigValue("EmailConfig", "smtp_host");
|
||||
String smtpPort = IniConfigUtils.getConfigValue("EmailConfig", "smtp_port");
|
||||
fromEmail = IniConfigUtils.getConfigValue("EmailConfig", "send_email_account");
|
||||
// 调整:使用带默认值的getConfigValue,配置缺失时自动兜底
|
||||
String smtpHost = IniConfigUtils.getConfigValue("EmailConfig", "smtp_host", DEFAULT_SMTP_HOST);
|
||||
String smtpPort = IniConfigUtils.getConfigValue("EmailConfig", "smtp_port", DEFAULT_SMTP_PORT);
|
||||
fromEmail = IniConfigUtils.getConfigValue("EmailConfig", "send_email_account", "");
|
||||
// 修复核心:给smtpAuthCode加final,适配Java7内部类访问规则
|
||||
final String smtpAuthCode;
|
||||
String tempAuthCode = IniConfigUtils.getConfigValue("EmailConfig", "send_email_auth_code");
|
||||
String tempAuthCode = IniConfigUtils.getConfigValue("EmailConfig", "send_email_auth_code", "");
|
||||
if (isEmpty(tempAuthCode)) {
|
||||
tempAuthCode = IniConfigUtils.getConfigValue("EmailConfig", "smtp_auth_code");
|
||||
tempAuthCode = IniConfigUtils.getConfigValue("EmailConfig", "smtp_auth_code", "");
|
||||
LogUtils.w(TAG, "未读取到send_email_auth_code,兜底读取smtp_auth_code配置");
|
||||
}
|
||||
smtpAuthCode = tempAuthCode; // 赋值给final变量
|
||||
fromNickname = IniConfigUtils.getConfigValue("EmailConfig", "from_nickname");
|
||||
emailSubjectPrefix = IniConfigUtils.getConfigValue("EmailConfig", "email_subject_prefix");
|
||||
verifyCodeContentTemplate = IniConfigUtils.getConfigValue("EmailConfig", "verify_code_email_content");
|
||||
fromNickname = IniConfigUtils.getConfigValue("EmailConfig", "from_nickname", "");
|
||||
emailSubjectPrefix = IniConfigUtils.getConfigValue("EmailConfig", "email_subject_prefix", DEFAULT_SUBJECT_PREFIX);
|
||||
verifyCodeContentTemplate = IniConfigUtils.getConfigValue("EmailConfig", "verify_code_email_content", DEFAULT_CONTENT_TEMPLATE);
|
||||
|
||||
LogUtils.d(TAG, "读取INI邮件配置:smtpHost[" + smtpHost + "] smtpPort[" + smtpPort + "] fromEmail[" + fromEmail + "]");
|
||||
if (isEmpty(smtpHost)) {
|
||||
LogUtils.e(TAG, "邮件核心配置缺失:smtp_host 未配置");
|
||||
return false;
|
||||
}
|
||||
if (isEmpty(smtpPort)) {
|
||||
LogUtils.e(TAG, "邮件核心配置缺失:smtp_port 未配置");
|
||||
return false;
|
||||
}
|
||||
// 核心配置非空校验(默认值兜底后,仅校验邮箱和授权码)
|
||||
if (isEmpty(fromEmail)) {
|
||||
LogUtils.e(TAG, "邮件核心配置缺失:send_email_account 未配置");
|
||||
return false;
|
||||
@@ -64,8 +66,6 @@ public class EmailSendUtils {
|
||||
LogUtils.e(TAG, "邮件核心配置缺失:send_email_auth_code / smtp_auth_code 均未配置");
|
||||
return false;
|
||||
}
|
||||
if (isEmpty(emailSubjectPrefix)) emailSubjectPrefix = "【AuthCenter 认证中心】";
|
||||
if (isEmpty(verifyCodeContentTemplate)) verifyCodeContentTemplate = "您的认证验证码为:{code},有效期5分钟,请及时使用,请勿泄露给他人!";
|
||||
|
||||
mailProps.put("mail.smtp.host", smtpHost);
|
||||
mailProps.put("mail.smtp.port", smtpPort);
|
||||
@@ -90,6 +90,28 @@ public class EmailSendUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ========== 新增:单元测试专用函数 ==========
|
||||
* 功能:自动检查初始化状态,未初始化则执行初始化 + 发送自测邮件
|
||||
* 适用场景:单元测试/控制台指令调用,无需手动前置初始化
|
||||
* @param testCode 测试验证码
|
||||
* @return 测试邮件发送成功返回true,否则false
|
||||
*/
|
||||
public static boolean test(String testCode) {
|
||||
LogUtils.d(TAG, "test() 函数调用,开始邮件工具类单元测试");
|
||||
// 1. 检查初始化状态,未初始化则自动调用initEmailConfig
|
||||
if (mailSession == null) {
|
||||
LogUtils.w(TAG, "邮件会话未初始化,自动执行配置初始化");
|
||||
boolean initResult = initEmailConfig();
|
||||
if (!initResult) {
|
||||
LogUtils.e(TAG, "自动初始化失败,单元测试终止");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 2. 调用自测函数发送测试邮件
|
||||
return sendSelfTestEmail(testCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码邮件(核心方法,适配INI主题/内容模板)
|
||||
* @param toEmail 接收方邮箱
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package cc.winboll.util;
|
||||
|
||||
import cc.winboll.LogUtils;
|
||||
import cc.winboll.Main;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -14,65 +16,104 @@ import java.util.Map;
|
||||
* 适配Android/assets目录与标准JVM文件路径,兼容Java7语法及Android API30
|
||||
* 提供INI配置加载、配置项获取核心能力,支持注释忽略与小节分组解析
|
||||
* 新增:Termux项目根目录config.ini自动加载 + 指定路径配置加载,适配现有标准INI格式
|
||||
* 调整:兜底配置路径关联 Main.DEFAULT_ROOT 静态常量,统一根目录管理
|
||||
* 升级:新增带默认值的配置获取方法,解决小节/键缺失导致的功能异常
|
||||
* 修复:移除冗余System.err输出,避免日志冲突;新增文件预校验,提升加载稳定性
|
||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2026-01-15 00:00:00
|
||||
* @LastEditTime 2026-01-20 22:00:00
|
||||
* @LastEditTime 2026-01-21 20:00:00
|
||||
*/
|
||||
public class IniConfigUtils {
|
||||
// 日志标记
|
||||
// ========== 静态常量(不可变) ==========
|
||||
private static final String TAG = "IniConfigUtils";
|
||||
// INI配置存储容器 <小节名, <配置键, 配置值>>
|
||||
private static final Map<String,Map<String,String>> iniConfigMap = new HashMap<String,Map<String,String>>();
|
||||
// 项目根目录config.ini路径(适配Termux环境,匹配你的目录结构)
|
||||
private static final String ROOT_CONFIG_PATH = System.getProperty("user.home") + "/AuthCenterConsoleApp/config.ini";
|
||||
private static final Map<String, Map<String, String>> iniConfigMap = new HashMap<String, Map<String, String>>();
|
||||
// 项目根目录config.ini路径(兜底路径关联 Main.DEFAULT_ROOT 静态常量)
|
||||
private static final String ROOT_CONFIG_PATH = Main.DEFAULT_ROOT + "/config.ini";
|
||||
|
||||
// ========== 工具方法:文件预校验 ==========
|
||||
/**
|
||||
* 校验文件是否存在且可读
|
||||
* @param filePath 文件绝对路径
|
||||
* @return true=有效,false=无效
|
||||
*/
|
||||
private static boolean checkFileValid(String filePath) {
|
||||
File configFile = new File(filePath);
|
||||
if (!configFile.exists()) {
|
||||
LogUtils.w(TAG, "【文件校验】文件不存在:" + filePath);
|
||||
return false;
|
||||
}
|
||||
if (!configFile.isFile()) {
|
||||
LogUtils.w(TAG, "【文件校验】路径不是文件:" + filePath);
|
||||
return false;
|
||||
}
|
||||
if (!configFile.canRead()) {
|
||||
LogUtils.w(TAG, "【文件校验】文件不可读:" + filePath);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ========== 配置加载方法 ==========
|
||||
|
||||
/**
|
||||
* 自动加载项目根目录的config.ini(Termux专用,一键读取,无需传流)
|
||||
* 启动自动调用,开箱即用,兼容现有INI格式
|
||||
*/
|
||||
public static void loadRootConfig() {
|
||||
LogUtils.d(TAG, "loadRootConfig 函数调用,开始加载项目根目录config.ini,路径:" + ROOT_CONFIG_PATH);
|
||||
LogUtils.d(TAG, "【函数调用】loadRootConfig(),加载路径:" + ROOT_CONFIG_PATH);
|
||||
// 前置文件校验
|
||||
if (!checkFileValid(ROOT_CONFIG_PATH)) {
|
||||
LogUtils.w(TAG, "【函数结束】loadRootConfig(),根目录配置加载跳过");
|
||||
return;
|
||||
}
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(ROOT_CONFIG_PATH);
|
||||
loadIniConfig(fis); // 复用原有加载逻辑,无需重复写解析代码
|
||||
loadIniConfig(fis);
|
||||
LogUtils.i(TAG, "【函数结束】loadRootConfig(),根目录配置加载成功");
|
||||
} catch (IOException e) {
|
||||
LogUtils.e(TAG, "加载根目录config.ini失败!请确认文件在 " + ROOT_CONFIG_PATH, e);
|
||||
System.err.println("❌ 配置文件未找到:" + ROOT_CONFIG_PATH + ",请检查文件存放路径");
|
||||
LogUtils.e(TAG, "【函数异常】loadRootConfig(),加载根目录配置失败", e);
|
||||
// 移除System.err输出,避免与测试类日志冲突
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
LogUtils.w(TAG, "关闭根目录配置文件流失败", e);
|
||||
LogUtils.w(TAG, "【流关闭异常】loadRootConfig(),关闭文件流失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【新增缺失方法】加载指定路径的INI配置文件
|
||||
* 加载指定路径的INI配置文件
|
||||
* 适配测试类传入的自定义路径,如/sdcard下的配置文件
|
||||
* @param configFilePath 配置文件的绝对路径
|
||||
*/
|
||||
public static void loadConfig(String configFilePath) {
|
||||
LogUtils.d(TAG, "loadConfig 函数调用,开始加载指定路径配置文件:" + configFilePath);
|
||||
LogUtils.d(TAG, "【函数调用】loadConfig(),加载路径:" + configFilePath);
|
||||
// 前置文件校验
|
||||
if (!checkFileValid(configFilePath)) {
|
||||
LogUtils.w(TAG, "【函数结束】loadConfig(),指定路径配置加载跳过");
|
||||
return;
|
||||
}
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
// 清空旧配置,避免多路径加载导致数据冲突
|
||||
iniConfigMap.clear();
|
||||
fis = new FileInputStream(configFilePath);
|
||||
loadIniConfig(fis);
|
||||
LogUtils.i(TAG, "指定路径配置文件加载成功:" + configFilePath);
|
||||
LogUtils.i(TAG, "【函数结束】loadConfig(),指定路径配置加载成功");
|
||||
} catch (IOException e) {
|
||||
LogUtils.e(TAG, "加载指定路径config.ini失败!请确认文件在 " + configFilePath, e);
|
||||
System.err.println("❌ 配置文件未找到:" + configFilePath + ",请检查文件存放路径");
|
||||
LogUtils.e(TAG, "【函数异常】loadConfig(),加载指定路径配置失败", e);
|
||||
// 移除System.err输出,避免与测试类日志冲突
|
||||
} finally {
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
LogUtils.w(TAG, "关闭指定路径配置文件流失败", e);
|
||||
LogUtils.w(TAG, "【流关闭异常】loadConfig(),关闭文件流失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,9 +124,9 @@ public class IniConfigUtils {
|
||||
* @param inputStream INI文件输入流(Android传assets流,JVM传文件流)
|
||||
*/
|
||||
public static void loadIniConfig(InputStream inputStream) {
|
||||
LogUtils.d(TAG, "loadIniConfig 函数调用,传入输入流参数:" + (inputStream == null ? "null" : inputStream.getClass().getName()));
|
||||
if(inputStream == null) {
|
||||
LogUtils.e(TAG, "加载INI失败:输入流为null");
|
||||
LogUtils.d(TAG, "【函数调用】loadIniConfig(),输入流:" + (inputStream == null ? "null" : inputStream.getClass().getName()));
|
||||
if (inputStream == null) {
|
||||
LogUtils.e(TAG, "【函数异常】loadIniConfig(),输入流为null");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -96,70 +137,100 @@ public class IniConfigUtils {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
line = line.trim();
|
||||
// 跳过空行、注释行(; 或 # 开头),兼容你的注释格式
|
||||
if(line.isEmpty() || line.startsWith(";") || line.startsWith("#")) {
|
||||
// 跳过空行、注释行(; 或 # 开头)
|
||||
if (line.isEmpty() || line.startsWith(";") || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
// 解析小节 [XXX],完美适配你的[EmailConfig]小节
|
||||
if(line.startsWith("[") && line.endsWith("]")) {
|
||||
// 解析小节 [XXX]
|
||||
if (line.startsWith("[") && line.endsWith("]")) {
|
||||
currentSection = line.substring(1, line.length() - 1).trim();
|
||||
iniConfigMap.put(currentSection, new HashMap<String,String>());
|
||||
LogUtils.d(TAG, "解析到INI小节,当前小节名:" + currentSection);
|
||||
iniConfigMap.put(currentSection, new HashMap<String, String>());
|
||||
LogUtils.d(TAG, "【解析小节】当前小节:" + currentSection);
|
||||
continue;
|
||||
}
|
||||
// 解析键值对(非空小节+包含=),适配你的key=value格式
|
||||
if(line.contains("=") && !currentSection.isEmpty()) {
|
||||
String[] keyValue = line.split("=", 2); // 按第一个=分割,兼容值里带=的场景
|
||||
if(keyValue.length == 2) {
|
||||
// 解析键值对(非空小节+包含=)
|
||||
if (line.contains("=") && !currentSection.isEmpty()) {
|
||||
String[] keyValue = line.split("=", 2);
|
||||
if (keyValue.length == 2) {
|
||||
String key = keyValue[0].trim();
|
||||
String value = keyValue[1].trim();
|
||||
iniConfigMap.get(currentSection).put(key, value);
|
||||
LogUtils.d(TAG, "解析配置项:小节[" + currentSection + "] 键[" + key + "] 值[" + value + "]");
|
||||
LogUtils.d(TAG, "【解析配置】[" + currentSection + "] " + key + "=" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
LogUtils.i(TAG, "INI配置加载完成,成功解析小节数量:" + iniConfigMap.size());
|
||||
LogUtils.i(TAG, "【函数结束】loadIniConfig(),配置加载完成,小节数:" + iniConfigMap.size());
|
||||
} catch (IOException e) {
|
||||
LogUtils.e(TAG, "加载INI配置时发生IO异常", e);
|
||||
LogUtils.e(TAG, "【函数异常】loadIniConfig(),IO异常", e);
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
LogUtils.d(TAG, "INI配置输入流已关闭");
|
||||
LogUtils.d(TAG, "【流关闭成功】loadIniConfig(),输入流已关闭");
|
||||
} catch (IOException e) {
|
||||
LogUtils.w(TAG, "关闭INI输入流失败", e);
|
||||
LogUtils.w(TAG, "【流关闭异常】loadIniConfig(),关闭输入流失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 配置获取方法 ==========
|
||||
|
||||
/**
|
||||
* 获取指定小节下的配置值
|
||||
* @param section 配置小节名(对应INI中[]包裹内容)
|
||||
* @param section 配置小节名
|
||||
* @param key 配置项键名
|
||||
* @return 配置值,小节不存在/键不存在均返回null
|
||||
* @return 配置值,小节/键不存在返回null
|
||||
*/
|
||||
public static String getConfigValue(String section, String key) {
|
||||
LogUtils.d(TAG, "getConfigValue 函数调用,传入参数:小节[" + section + "] 键[" + key + "]");
|
||||
if(section == null || key == null) {
|
||||
LogUtils.w(TAG, "获取配置失败:小节名或键名为null");
|
||||
LogUtils.d(TAG, "【函数调用】getConfigValue(),小节:" + section + " 键:" + key);
|
||||
if (section == null || key == null) {
|
||||
LogUtils.w(TAG, "【参数异常】getConfigValue(),小节或键为null");
|
||||
return null;
|
||||
}
|
||||
if(!iniConfigMap.containsKey(section)) {
|
||||
LogUtils.w(TAG, "获取配置失败:不存在小节[" + section + "]");
|
||||
if (!iniConfigMap.containsKey(section)) {
|
||||
LogUtils.w(TAG, "【获取失败】getConfigValue(),不存在小节[" + section + "]");
|
||||
return null;
|
||||
}
|
||||
String value = iniConfigMap.get(section).get(key);
|
||||
LogUtils.d(TAG, "获取配置结果:小节[" + section + "] 键[" + key + "] 值[" + value + "]");
|
||||
LogUtils.d(TAG, "【获取结果】getConfigValue(),值:" + value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 【可选新增】获取所有配置小节,便于调试和配置完整性校验
|
||||
* @return 所有小节名称的集合
|
||||
* 【重载方法】获取指定小节下的配置值,支持默认值降级
|
||||
* 解决小节/键缺失导致的空指针或功能中断问题
|
||||
* @param section 配置小节名
|
||||
* @param key 配置项键名
|
||||
* @param defaultValue 降级默认值
|
||||
* @return 配置值,缺失则返回默认值
|
||||
*/
|
||||
public static String getConfigValue(String section, String key, String defaultValue) {
|
||||
LogUtils.d(TAG, "【函数调用】getConfigValue(),小节:" + section + " 键:" + key + " 默认值:" + defaultValue);
|
||||
if (section == null || !iniConfigMap.containsKey(section)) {
|
||||
LogUtils.w(TAG, "【降级处理】getConfigValue(),小节[" + section + "]不存在,使用默认值");
|
||||
return defaultValue;
|
||||
}
|
||||
Map<String, String> sectionMap = iniConfigMap.get(section);
|
||||
if (key == null || !sectionMap.containsKey(key)) {
|
||||
LogUtils.w(TAG, "【降级处理】getConfigValue(),键[" + key + "]不存在,使用默认值");
|
||||
return defaultValue;
|
||||
}
|
||||
String value = sectionMap.get(key);
|
||||
LogUtils.d(TAG, "【获取结果】getConfigValue(),值:" + value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有配置小节,便于调试和配置完整性校验
|
||||
* @return 所有配置的深拷贝,避免外部修改内部容器
|
||||
*/
|
||||
public static Map<String, Map<String, String>> getAllConfig() {
|
||||
return new HashMap<String, Map<String, String>>(iniConfigMap);
|
||||
Map<String, Map<String, String>> copyMap = new HashMap<String, Map<String, String>>();
|
||||
for (Map.Entry<String, Map<String, String>> entry : iniConfigMap.entrySet()) {
|
||||
copyMap.put(entry.getKey(), new HashMap<String, String>(entry.getValue()));
|
||||
}
|
||||
return copyMap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user