Java程序设计-07输入输出流.ppt
计算机科学与技术学院赵志崑,Java程序设计,Java程序的输入输出,以一个小应用为例,介绍Java的输入输出机制。,小应用,需求分析需要实现的功能点Java中的实现方法具体代码总结与扩展,随机点名器,功能:设计开发一个Java程序,每节课可以随机抽取几名同学点名,达到随机点名的目的。,数据来源:教务系统提供的学生名单(文本文件),随机选出10个学生,程序流程与要点,文本文件,屏幕打印,要点一:读文件,Java中文件以流(Stream)的方式读写,将程序的输入输出看作是数据的流动,一个流是一个字节的序列。流的使用不局限于文件读写,还可用于网络传输、键盘输入、屏幕输出等和程序输入输出有关的一切活动。根据用途,Java中提供了几十种流,类库中为每一种流提供一个类,用于创建流(对象)。,读文件流,用于读文本文件内容的流是FileReader,主要方法:FileReader(String filename):构造函数,创建流。int read():读一个字节,若读到文件结尾返回-1。void close():关闭流。,FileReader fr=new FileReader(“Students.txt”);,int d=fr.read();,fr.close();,2,0,-1,学生数据读入,从文件students.txt中读入学生数据。/Selector.javaimport java.io.*;public class Selector public static void main(String args)throws ExceptionFileReader fr=new FileReader(Students.txt);int c=fr.read();while(c!=-1)System.out.print(char)c);c=fr.read();fr.close();说明:文件Students.txt必须放在同一个目录下。必须在主函数声明处加入“throws Exception”将异常全部交给虚拟机处理,按行读取,BufferedReader类能实现按行读取的功能,主要方法:BufferedReader(Reader reader):构造函数,创建流。String readLine():读一行字符,若读到文件结尾返回null。void close():关闭流。,字符,字符串,20080854101 伦永涛 2008计算机科学与技术1,BufferedReader br=new BufferedReader(fr);,String s=br.readLine();,br.close();,null,按行读取数据的代码,按行读取学生数据的代码如下:,/Selector.javaimport java.io.*;public class Selector public static void main(String args)throws Exception FileReader fr=new FileReader(Students.txt);BufferedReader br=new BufferedReader(fr);String s=br.readLine();while(s!=null)System.out.println(s);s=br.readLine();br.close();fr.close();,FileReader,文件,流的嵌套,要点二:数据存放,从文件读入的数据是一个个字符串,如何在程序中存放?,20080854101 伦永涛,20080854102 王楚尧,20080854103 李燕,用数组来保存批量数据,创建一个字符串数组,将读入的数据依次放入,用一个整数型变量记录数据个数,并作为空闲位置的指针,String students=new String100;,int count=0;,studentscount=s;,count+;,1,2,3,数据存放的代码,加入数据存放后的代码如下:,/Selector.javaimport java.io.*;public class Selector public static void main(String args)throws Exception String students=new String100;int count=0;FileReader fr=new FileReader(Students.txt);BufferedReader br=new BufferedReader(fr);String s=br.readLine();while(s!=null)studentscount=s;count+;s=br.readLine();br.close();fr.close();,要点三:随机选取,学生信息存放在数组中,对应下标为0到count-1。如何从中随机选出1个?(产生一个0到count-1的随机整数),Java提供Random类来创建随机数对象,方法包括:Random():构造函数,创建随机数对象,初始值为当前时间。nextInt(int n):产生一个0到n之间的随机整数。要选出几个,就循环调用几次。,Random rand=new Random();,int n=rand.nextInt(count);,Random的实现利用了混沌函数:Xn+1=f(Xn),Xn+1和Xn之间几乎没有任何规律;X0为对象创建时的系统时钟值(从1970年1月1日0时0分0秒到当前经过的毫秒数)。,避免重复选择,避免重复选择:将选中过的学生数据从数组中删除,20080854101 伦永涛,20080854102 王楚尧,20080854103 李燕,0,1,2,3,4,98,99,students,79,count,20080854104 董风华,20080854105 李晶,77,78,79,20080854239 秦露,20080854240 王萍,用最后一名学生替换选中的学生,总数量减1,studentsn=studentscount-1;,count-;,78,要点四:结果存入文件,将选中学生的名单保存到文件selected.txt中。,向文件中写入字符用的流是FileWriter,相关方法是:FileWriter(String filename):构造函数,创建文件输出流。write(String s,int start,int end):将字符串s中第start个字符到第end个字符写入文件。close():关闭流,保证文件内容写入磁盘。,FileWriter fw=new FileWriter(Selected.txt);,fw.write(line,0,line.length();,fw.close();,要换行,只需要写入一个”rn”字符串,20080854219 徐飞飞 2008计算机科学与技术2,20080854201 张慧丽 2008计算机科学与技术2,写文件的代码,将结果写入文件的代码如下:,Random rand=new Random();int selectCount=10;FileWriter fw=new FileWriter(Selected.txt);for(int i=0;iselectCount;i+)int n=rand.nextInt(count);String line=studentsn;System.out.println(line);line+=rn;fw.write(line,0,line.length();studentsn=studentscount-1;count-;fw.close();,Java中的流,Java中提供了几十种流,本例中用到了三个:FileReaderBufferedReaderFileWriter,所有流都派生自四个最基本的流:Reader、WriterInputStream、OutputStream,总结与说明,文本文件,屏幕打印,改进1自动生成文件名,改进2配置选出个数,改进3分切数据字段,改进1自动生成文件名,问题:生成的文件名始终为selected.txt;后一次生成的结果会覆盖掉前一次的结果。解决方法:为输出文件名编号,第一次结果为no1.txt,第二次为no2.txt,这样就不会覆盖了。文件编号规则为:如果不存在no1.txt文件,则结果为no1.txt;如果不存在no2.txt文件,则结果为no2.txt;,自动生成文件名,自动生成文件名利用了File类其exists()方法可以判断文件是否存在;File类的对象可以直接用于创建FileWriter流。int no=0;File outf;do no+;outf=new File(No+no+.txt);while(outf.exists();FileWriter fout=new FileWriter(outf);,改进2配置选出人数,问题:每次固定选出10名学生,过于死板;如果某次想选出15名学生就需要改源程序,比较麻烦。解决方法:使用main函数的参数,即运行时,可以带参数,如java selector 15大多数情况下都选出10名,所以为方便起见,应该在不提供参数的情况下,默认为选出10名。,main函数参数的使用,main函数的参数为字符串数组(String)。第一个参数下标为0。public static void main(String args)throws IOException int selectedCount=10;if(args.length 0)selectedCount=Integer.parseInt(args0);,改进3分切数据字段,问题:对输入的字符串没有进行分析,所以很多操作无法进行,如按姓名排序、按班级抽取等;解决方法:读入数据时,对各字段进行解析,各字段分别存放;输出时再将这些字段组合成字符串。,Student类,为了保存格式化的数据定义Student类:class Student private String id;/学号private String name;/姓名private String department;/学院public void parseStudent(String str)/字符串解析public String toString()/生成字符串数据保存在Student类型的对象数组中:Student students=new Student100;数据读入时格式化:Studentstudent=new Student();student.parseStudent(line);studentscount=student;count+;数据输出:line=studentsj.toString();,设计parseStudent方法,主要使用了字符串处理中的切词类StringTokenizer,该类提供的方法可以根据空格符将字符串分切成多个词。public void parseStudent(String str)int tokenCount;StringTokenizer t=new StringTokenizer(str);tokenCount=t.countTokens();id=t.nextToken();/学号name=t.nextToken();/姓名department=t.nextToken();/班级,设计toString方法,主要输出三个字段:学号、姓名和班级。学号的长度都一致。姓名的长度不一致,有两个字有三个字,会对后面的班级字段的起始位置产生影响。因此,加入姓名后,采用了一条对齐语句。public String toString()String s=id+name;for(int l=s.length();l 21;l+)s+=“”;/对齐,引号中为两个空格return s+department;,实验作业,文本文件读写将students.txt中数据全部读入内存数组;将学生排序全部反转,即第一位变成最后一位,最后一位变为第一位;将结果保存到另一个文件中;students.txt文件从文件交换处下载。,后续完善,随机点名器程序将贯穿本课程后面的学习,随机点名器,感谢!,本课程全部ppt和源代码可以从“网上课堂”下载,