在上一章我们学习了怎样使用Scanner类的对象解析字符串中的数据,那么这一节我们将学习怎样使用Scanner类的对象解析文件中的数据。
应用程序可能需要解析文件中的特殊数据,此时,应用程序可以把文件的内容全部读入内存后,再解析所需要的内容,其优点是处理速度快,但如果读入的内容较大将消耗较多的内存,即以空间换取时间。
这一节主要介绍怎样借助Scanner类和正则表达式来解析文件,比如,要解析出文件中的特殊单词、数字等信息。使用Scanner类和正则表达式来解析文件的特点是以时间换取空间,即解析的速度相对较慢,但节省内存。
创建Scanner对象,并指向要解析的文件,例如:
Filefile=newFile(hello.java);Scannersc=newScanner(file);
那么sc将空格作为分隔标记,调用next()方法依次返回file中的单词,如果file最后一个单词已被next()方法返回,sc调用hasNext()将返回false,否则返回true。
另外,对于数字型的单词,比如108,167.92等可以用nextInt()或nextDouble()方法来代替next()方法,即sc可以调用nextInt()或nextDouble()方法将数字型单词转化为int或double数据返回,但需要特别注意的是,如果单词不是数字型单词,调用nextInt()或nextDouble()方法将发生InputMismatchException异常,在处理异常时可以调用next()方法返回该非数字化单词。
创建Scanner对象,指向要解析的文件,并使用useDelimiter方法指定正则表达式作为分隔标记,例如:
Filefile=newFile(hello.java);Scannersc=newScanner(file);sc.useDelimiter(正则表达式);
那么sc将正则表达式作为分隔标记,调用next()方法依次返回file中的单词,如果file最后一个单词已被next()方法返回,sc调用hasNext()将返回false,否则返回true。
另外,对于数字型的单词,比如1979,0.618等可以用nextInt()或nextDouble()方法来代替next()方法,即sc可以调用nextInt()或nextDouble()方法将数字型单词转化为int或double数据返回,但需要特别注意的是,如果单词不是数字型单词,调用nextInt()或nextDouble()方法将发生InputMismatchException异常,那么在处理异常时可以调用next()方法返回该非数字化单词。
例如,使用正则表达式(匹配所有非数字字符串)String regex=[^0123456789.]+作为分隔标记解析student.txt文件中的学生成绩,并计算平均成绩。
student.txt
张三的成绩是70分,李四的成绩是80分,赵五的成绩是90分。
代码如下:
importjava.io.*;importjava.util.*;publicclassMain{publicstaticvoidmain(Stringargs[]){Filefile=newFile(student.txt);Scannersc=null;intcount=0;doublesum=0;try{doublescore=0;sc=newScanner(file);sc.useDelimiter([^0123456789.]+);while(sc.hasNextDouble()){score=sc.nextDouble();count++;sum=sum+score;System.out.println(score);}doubleaver=sum/count;System.out.println(平均成绩:+aver);}catch(Exceptionexp){System.out.println(exp);}}}