Android Java中If-Else与Break语句的问题排查求助
解决Android文件读取中温度标识匹配的逻辑冲突问题
我明白你现在的困境——要么提前break导致错过目标标识,要么去掉break引发崩溃或重复提示。核心问题出在你在遍历文件行的过程中过早地执行了else逻辑,而不是等整个文件遍历完成后再统一判断是否找到标识。
先拆解下你的需求:
- 从SharedPreferences获取
filename,遍历指定目录下的文件 - 在文件内容中找到匹配
filename的行 - 若该文件中存在
--TEMPERATURE UP--标识,就读取后续内容并发送指令 - 若不存在该标识,显示提示Toast
原代码的核心问题
- 原代码在内部while循环中,每读一行如果不是目标标识就立刻弹Toast并
break,这会导致文件还没读完就中断,即使后面有目标标识也找不到 - 去掉
break的话,会一直循环到文件结束,重复触发Toast提示,甚至因为未正确关闭资源或空指针导致崩溃 - 你更新后的代码逻辑写反了:
if (hasTempDisplayProfile)时弹Toast,这和需求完全相反,应该是没找到标识时才弹
修正后的完整代码
下面是调整后的代码,我加了详细注释,解决了所有逻辑问题和潜在的异常:
public void tempUp() { // 1. 获取目标filename,去除首尾空格避免匹配错误 SharedPreferences sharedTest = getSharedPreferences("MySharedTest", Context.MODE_PRIVATE); String targetFilename = sharedTest.getString("filename", "").trim(); Log.d("Target filename: ", targetFilename); // 2. 检查目标目录是否可访问 File dir = new File(path); File[] files = dir.listFiles(); if (files == null || files.length == 0) { Log.e("tempUp", "Directory is empty or inaccessible"); Toast.makeText(TestScreen.this, "Failed to access profile directory", Toast.LENGTH_LONG).show(); return; } boolean foundTargetFile = false; // 3. 遍历目录下的文件 for (File f : files) { if (!f.isFile()) continue; BufferedReader inputStream = null; try { inputStream = new BufferedReader(new FileReader(f)); String currentLine; boolean foundFilenameInFile = false; // 先检查当前文件是否包含目标filename行 while ((currentLine = inputStream.readLine()) != null) { if (currentLine.trim().equals(targetFilename)) { foundFilenameInFile = true; foundTargetFile = true; break; // 找到filename后停止读取当前文件的其他行 } } // 4. 如果找到filename,继续查找温度标识 if (foundFilenameInFile) { BufferedReader reader = new BufferedReader(new FileReader(f)); String line; boolean hasTempUpFlag = false; String msValue = null; // 遍历文件查找--TEMPERATURE UP-- while ((line = reader.readLine()) != null) { if (line.equals("--TEMPERATURE UP--")) { hasTempUpFlag = true; msValue = reader.readLine(); // 读取标识后的参数行 break; // 找到标识后停止遍历 } } // 5. 遍历完成后统一判断逻辑 if (hasTempUpFlag && msValue != null) { Log.d("temp up: ", msValue); // 启动子线程发送指令(避免阻塞UI) new Thread(() -> { String message = "\u000704NTX" + msValue + "\r"; byte[] byteArray = message.getBytes(); try { SharedPreferences prefx = getSharedPreferences("Device_Data", Context.MODE_PRIVATE); String deviceIp = prefx.getString("local_ip", "").trim(); if (deviceIp.isEmpty()) { // 回到UI线程提示错误 runOnUiThread(() -> Toast.makeText(TestScreen.this, "Device IP not configured", Toast.LENGTH_LONG).show() ); return; } // 建立Socket连接并发送数据 Socket socket = new Socket(deviceIp, 8070); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); out.write(byteArray); out.flush(); // 关闭资源,避免泄漏 out.close(); socket.close(); } catch (Exception e) { e.printStackTrace(); // 发送失败时回到UI线程提示 runOnUiThread(() -> Toast.makeText(TestScreen.this, "Failed to send temperature command", Toast.LENGTH_LONG).show() ); } }).start(); } else { // 未找到温度标识,显示提示 Toast.makeText(TestScreen.this, "There is no Temperature Display for this profile.", Toast.LENGTH_LONG).show(); } reader.close(); // 关闭文件读取流 } } catch (IOException e) { e.printStackTrace(); Toast.makeText(TestScreen.this, "Failed to read profile file", Toast.LENGTH_LONG).show(); } finally { // 确保资源被关闭,避免泄漏 try { if (inputStream != null) inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } // 找到目标文件后停止遍历其他文件,提升效率 if (foundTargetFile) break; } // 如果遍历完所有文件都没找到匹配的filename if (!foundTargetFile) { Toast.makeText(TestScreen.this, "Matching profile file not found", Toast.LENGTH_LONG).show(); } }
关键改进点
- 逻辑顺序调整:先确认文件包含目标filename,再查找温度标识,避免无效遍历
- 统一判断时机:等文件遍历完成后,再根据布尔变量
hasTempUpFlag决定执行哪段逻辑,不会提前中断循环 - 资源泄漏修复:所有打开的流和Socket都被正确关闭
- 异常处理优化:增加了目录为空、IP未配置等边界情况的处理,且所有Toast都确保在UI线程执行(子线程中用
runOnUiThread) - 效率提升:找到目标文件后立刻停止遍历其他文件,减少不必要的IO操作
这样修改后,就不会出现之前的两难情况:找到标识时执行发送逻辑,没找到时显示提示,且不会崩溃。
内容的提问来源于stack exchange,提问作者Kelvin JigSawing
相关产品推荐
相关产品推荐

