我正在维护一些旧版Android代码,该代码从文本文件中读取我们产品的“校准”值。从理论上讲,用户可以手动调整校准文件,因此我们每10秒钟重新加载一次文件以检查新值。用户还可以将文件弄乱,因此,如果发现文件不可读/无法解析,我们将写出默认版本的“校准”。
以下是我们阅读和解析术语的相关代码:
public boolean ReadCalibFromFile() {
boolean res = true;
String title = null;
String data = null;
try {
File direct = new File(WSDataStorageUtils.getInstance().getCurrentDirLocation());
if (!direct.exists()) {
File filesDirectory = new File(WSDataStorageUtils.getInstance().getCurrentDirLocation());
filesDirectory.mkdirs();
}
File calib=new File(new File(WSDataStorageUtils.getInstance().getCurrentDirLocation()), currentCalibFile + ".txt");
Logger.i(tag, "Using calibration file: " + currentCalibFile + ".txt");
if(!calib.exists()){
Logger.i(tag, "Calibration file doesn't exist! Recreating...");
SaveCalibFiles();
// having saved the standard files, if we can't find the file we might have a wrong name
if (!calib.exists()) {
Logger.e(tag, "This file: " + currentCalibFile + ", doesn't exist, returning to default");
currentCalibFile = DEFAULT_CALIB_FILE;
calib=new File(new File(WSDataStorageUtils.getInstance().getCurrentDirLocation()), currentCalibFile + ".txt");
}
if (!calib.exists()) { // even after returning to default value
// we are really screwed
Logger.e(tag, "Can't even recover to default file! This is bad!");
return false;
}
}
Scanner read = new Scanner(calib);
read.useDelimiter("=|\\n");
while (read.hasNext()) {
title = read.next();
data = read.next();
if (!nextData(data, title)) {
Logger.e(tag, "Error in reading from Calibration file");
Logger.e(tag, "title = " + title + " data = " + data);
res = false;
break;
}
}
read.close();
if(VersionChecked == false) {
res = false;
}
} catch (Exception e) {
e.printStackTrace();
Logger.e("ReadCalibFromfile", "Received an exception: " + e.getMessage());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String stackTrace = sw.toString();
Logger.e("ReadCalibFromFile", stackTrace);
Logger.e(tag, "Last good values from file were:");
Logger.e(tag, "title = " + title + " data = " + data);
res = false;
}
return res;
}
在大多数情况下,这种方法都能正常工作。我们在周末运行该应用程序(没有人在编辑校准文件),而在深夜,该文件有某种错误。该代码通过覆盖旧文件“修复”了错误-但这是我不理解的错误。
节录的日志:
2018-07-13 00:25:12.441 [Thread-240] INFO Calibration: Using calibration file: name.txt
2018-07-13 00:25:12.470 [Thread-240] ERROR ReadCalibFromfile: Received an exception: null
2018-07-13 00:25:12.470 [Thread-240] ERROR ReadCalibFromFile: java.util.NoSuchElementException
at java.util.Scanner.next(Scanner.java:968)
at java.util.Scanner.next(Scanner.java:941)
at com.mycompany.myapp.Calibration.ReadCalibFromFile(Calibration.java:190)
at com.mycompany.myapp.Calibration.run(Calibration.java:108)
at java.lang.Thread.run(Thread.java:818)
2018-07-13 00:25:12.471 [Thread-240] ERROR Calibration: Last good values from file were:
2018-07-13 00:25:12.471 [Thread-240] ERROR Calibration: title = Version=1.1
firstRegionLimit=8
secondRegionLimit=50
CoafPressRegion0_0=-3.0
CoafPressRegion0_1=3.0
CoafPressRegion0_2=0.01
CoafPressRegion0_3=0.0
CoafPressRegion1_0=1.5
CoafPressRegion1_1=1.4
CoafPressRegion1_2=0.02
CoafPressRegion1_3=0.0
CoafPressRegion2_0=-10.0
CoafPressRegion2_1=5.0
CoafPressRegion2_2=0.015
CoafPressRegion2_3=0.0
*= " Version : VERSION NUMBER - PLEASE DON'T CHANGE"
*= " firstRegionLimit : the high limit of the first range "
*= " secondRegionLimit : the high limit of the second range "
*= " mCoafPressRegion : the coefficient for a certain region "
data = null
如您所见-尽管分隔符已设置为“ =”和“ \ n”,但该应用程序找不到任何分隔符。需要明确的是,此代码99%的时间都可以在此文件上正常工作。整个第一个“读取”(应该由定界符决定)包含一个包含许多定界符的文本(即使您不相信我每行之间都有真实的'\ n',也可以看到'=')。
当此函数返回false时,我重写了文件,然后一切正常。...再过几个小时,每10秒钟可以正确读取一次,然后在8个小时多一点后又出现了同样的问题。
还有其他人遇到过这样的问题吗?我不知道这是一个定时问题,因为该文件每10秒读取一次,并且正确关闭了之前的时间。