我使用以下代码将数组列表中的元素写入文件,稍后使用StringTokenizer进行检索。对于其他3个数组列表,它可以完美地工作,但对于这个特定的数组列表,它在使用. nexttoken()读取时抛出异常,并且使用. counttokens()进行进一步的故障排除显示它在文件中只有1个token。写和读的分隔符是相同的- ","和其他数组列表一样
我很困惑为什么当我没有改变代码结构时,它不像其他数组那样工作。
================= 写入文件 ==================
public static void copy_TimeZonestoFile(ArrayList<AL_TimeZone> timezones, Context context){
try {
FileOutputStream fileOutputStream = context.openFileOutput("TimeZones.dat",Context.MODE_PRIVATE);
OutputStreamWriter writerFile = new OutputStreamWriter(fileOutputStream);
int TZsize = timezones.size();
for (int i = 0; i < TZsize; i++) {
writerFile.write(
timezones.get(i).getRegion() + "," +
timezones.get(i).getOffset() + "n"
);
}
writerFile.flush();
writerFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
========== 读取文件(嵌套在线程/运行的组合 )===========
public void run() {
if (fileTimeZones.exists()){
System.out.println("Timezone file exists. Loading.. File size is : " + fileTimeZones.length());
try{
savedTimeZoneList.clear();
BufferedReader reader = new BufferedReader(new InputStreamReader(openFileInput("TimeZones.dat")));
String lineFromTZfile = reader.readLine();
while (lineFromTZfile != null ){
StringTokenizer token = new StringTokenizer(lineFromTZfile,",");
AL_TimeZone timeZone = new AL_TimeZone(token.nextToken(),
token.nextToken());
savedTimeZoneList.add(timeZone);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
}
=================== 跟踪 ======================
I/System.out: Timezone file exists. Loading.. File size is : 12373
W/System.err: java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at com.cryptotrac.trackerService$1R_loadTimeZones.run(trackerService.java:215)
W/System.err: at java.lang.Thread.run(Thread.java:764)
看来这行代码导致了java.util.NoSuchElementException
被抛出。
AL_TimeZone timeZone = new AL_TimeZone(token.nextToken(), token.nextToken());
这可能意味着文件TimeZones.dat中至少有一行不能精确包含两个用逗号分隔的字符串。
这可以很容易地检查,通过确保您从文件中读取的行是一个有效的行,然后再尝试解析它。
使用java.lang.String
类的拆分方法优于使用StringTokenizer
类。实际上,类StringTokenizer
的javadoc声明如下:
StringTokenizer是一个遗留类,出于兼容性原因保留了它,尽管不鼓励在新代码中使用它。建议任何寻求此功能的人使用String的split方法或java.util.regex包来代替。
试试下面的
String lineFromTZfile = reader.readLine();
while (lineFromTZfile != null ){
String[] tokens = lineFromTZfile.split(",");
if (tokens.length == 2) {
// valid line, proceed to handle it
}
else {
// optionally handle an invalid line - maybe write it to the app log
}
lineFromTZfile = reader.readLine(); // Read next line in file.
}
可能有很多地方是错误的,因为我实际上希望您进入无限循环,因为您只读取文件的第一行,然后重复解析它。
你应该检查以下内容:
- 确保正确地写入文件。书面文件到底包含了什么?每一行的末尾都有新的行吗?
- 确保写入的数据(在本例中为"区域")和"offset")永远不要包含逗号,否则解析将中断。我预计很有可能"地区">
- 在读取文件时,您总是需要假设文件(格式)已损坏。例如,假设
readLine
将返回空行或包含多个或少于一个逗号的内容。