Java高级-JavaIO系统.ppt
Java IO系统,第 二 章,本章相关词汇,本章目标,复习IO包,强化区分字符/字节的区别运用FileInputStream类和FileOutputStream类完成复制文件的功能运用FileReader类和FileWriter类配合BufferedReader类和BufferedWriter类来进行字符的读取和写入功能运用InputStreamReader类和BufferedReader类来完成控制台输入的功能清楚PrintWriter类的使用方式:System.out JSP:out,java.io包简介,java.io包也是Java内置的包,其中包含一系列对文件和目录的属性进行操作,对文件进行读写操作的类;程序中如果要使用到该包中的类,对文件或流进行操作,则必须显式地声明如下语句:import java.io.*;,文件,什么是文件?文件可以认为是相关记录或存放在一起的数据的集合;文件一般是存放在磁盘上的,例如:硬盘、软盘和光盘等等。,File类,File类的对象不但可以表示文件,还可以表示目录,在程序中一个File类对象可以代表一个文件或目录;当创建一个文件对象后,就可以利用它来对文件或目录的属性进行操作,如:文件名、最后修改日期、文件大小等等;需要注意的是,File对象并不能直接对文件进行读/写操作,只能查看文件的属性;,File类的构造方法,File类的构造方法有4种重载方式,常用的如下:如:/在当前目录下创建一个与aaa.txt文件名相关联的文件对象File f1=new File(aaa.txt);/指明详细的路径以及文件名,请注意双斜线File f2=new File(D:JavaHello.java);,File类中的常用方法,File类示例,public class FileDemo public static void main(String args)/创建一个文件对象,使之与一个文件关联 File file=new File(test.txt);/显示与文件有关的属性信息 System.out.println(文件或目录是否存在:+file.exists();System.out.println(是文件吗:+file.isFile();System.out.println(是目录吗:+file.isDirectory();System.out.println(名称:+file.getName();System.out.println(绝对路径:+file.getAbsolutePath();System.out.println(最后修改时间:+file.lastModified();System.out.println(文件大小:+file.length();,stream(流),流是指一连串流动的数据信号,是以先进先出的方式发送和接收数据的通道。,InputStream,来自数据源的数据流,OutputStream,流向目的地的数据流,流(续),流的类型,根据流动方向的不同,流分为输入流和输出流;对于输入和输出流,由于传输格式的不同,又分为字节流和字符流:字节流是指8位的通用字节流,以字节为基本单位,在java.io包中,对于字节流进行操作的类大部分继承于InputStream(输入字节流)类和OutputStream(输出字节流)类;字符流是指16位的Unicode字符流,以字符(两个字节)为基本单位,非常适合处理字符串和文本,对于字符流进行操作的类大部分继承于Reader(读取流)类和Writer(写入流)类。,使用FileInputStream类读文件,FileInputStream类称为文件输入流,继承于InputStream类,是进行文件读操作的最基本类;它的作用是将文件中的数据输入到内存中,我们可以利用它来读文件;由于它属于字节流,因此在读取Unicode字符(如中文)的文件时可能会出现问题。,FileInputStream类的构造方法,FileInputStream类的构造方法有3种重载方式,以下是常用的几种。,FileInputStream类的常用方法,FileInputStream对象读文件示例1,public class FileInputStreamDemo1 public static void main(String args)try File file=new File(test.txt);/创建文件对象/使用文件对象创建文件输入流对象,相当于打开文件 FileInputStream fis=new FileInputStream(file);for(int i=0;i file.length();i+)char ch=(char)(fis.read();/循环读取字符 System.out.print(ch);System.out.println();fis.close();/关闭流 catch(FileNotFoundException fnfe)System.out.println(文件打开失败。);catch(IOException ioe)ioe.printStackTrace();,FileInputStream对象读文件示例2,public class FileInputStreamDemo2 public static void main(String args)try File file=new File(test.txt);/创建文件对象 FileInputStream fis=new FileInputStream(file);/根据文件的字节长度创建字节数组 byte buf=new byte(int)(file.length();fis.read(buf);/读取文件中的数据存放到字节数组中 String str=new String(buf);/利用字节数组创建字符串 System.out.println(str);/打印字符串 fis.close();/关闭流 catch(FileNotFoundException fnfe)System.out.println(文件打开失败。);catch(IOException ioe)ioe.printStackTrace();,使用FileOutputStream类写文件,FileOutputStream类称为文件输出流,继承于OutputStream类,是进行文件写操作的最基本类;它的作用是将内存中的数据输出到文件中,我们可以利用它来写文件。,FileOutputStream类的构造方法,FileOutputStream类的构造方法有5种重载方式,以下是常用的几种。,FileOutputStream类的常用方法,FileOutputStream对象写文件示例1,public class FileOutputStreamDemo1/在函数内部不进行异常处理,将异常抛出函数外部 public static void main(String args)throws IOException String str=Hello world!;File file=new File(test.txt);/创建文件对象/通过文件对象创建文件输出流对象/附加第二个参数true,指定进行文件追加,默认为不追加 FileOutputStream fos=new FileOutputStream(file,true);/逐个将字符写入到文件中 for(int i=0;i str.length();i+)fos.write(str.charAt(i);fos.close();/关闭流,FileOutputStream对象写文件示例2,public class FileOutputStreamDemo2/在函数内部不进行异常处理,将异常抛出函数外部 public static void main(String args)throws Exception String str=I Love Java;/通过文件名创建文件输出流对象 FileOutputStream fos=new FileOutputStream(test.txt);/将字符串转化为字节数组 byte buffer=str.getBytes();/将字节数组中包含的数据一次性写入到文件中 fos.write(buffer);/关闭流 fos.close();,FileInputStream/FileOutputStream小结,FileInputStream类和FileOutputStream类是成对出现的,一个进行输入(读文件)操作,一个进行输出(写文件)操作;由于采用字节方式进行数据传输,不必考虑数据的格式问题,这两个类对文件操作的效率较高;可以使用这两个类完成复制文件的操作。,复制文件示例,public class CopyFileDemo public static void main(String args)throws IOException File srcFile=new File(src.dat);/源文件对象 File destFile=new File(dest.dat);/目标文件对象 if(!(destFile.exists()/判断目标文件是否存在 destFile.createNewFile();/如果不存在则创建新文件/使用源文件对象创建文件输入流对象 FileInputStream fis=new FileInputStream(srcFile);/使用目标文件对象创建文件输出流对象 FileOutputStream fos=new FileOutputStream(destFile);byte buf=new byte1024;/创建字节数组,作为临时缓冲 System.out.println(开始复制文件.);while(fis.read(buf)!=-1)/循环从文件输入流中读取数据 fos.write(buf);/写入到文件输出流中 System.out.println(文件复制成功!);fis.close();/关闭流 fos.close();,字符流,FileInputStram类和FileOutputStream类虽然可以高效率地读/写文件,但对于Unicode编码的文件,使用它们有可能出现乱码;考虑到Java是跨平台的语言,要经常操作Unicode编码的文件,使用字符流操作文件是有必要的;使用字符流将涉及到以下4个类:FileReader类和FileWriter类;BufferedReader类和BufferedWriter类。,FileReader类,FileReader类称为文件读取流,允许以字符流的形式对文件进行读操作,其构造方法有3种重载方式,以下是常用的几种:该类将从文件中逐个地读取字符,效率比较低下,因此一般将该类对象包装到缓冲流中进行操作。,BufferedReader类,BufferedReader类主要为字符流提供缓冲,以提高效率,其构造方法有2种重载方式,以下是常用的几种:以下是BufferedReader类的常用方法:,FileReader配合BufferedReader读文件示例,public class RraderDemo public static void main(String args)throws IOException File file=new File(test.txt);/通过文件对象创建文件读取流对象 FileReader fr=new FileReader(file);/将文件读取流包装成缓冲读取流 BufferedReader br=new BufferedReader(fr);String str;while(str=br.readLine()!=null)/逐行读取数据 System.out.println(str);br.close();/关闭流 fr.close();/关闭流,FileWriter类,FileWriter类称为文件写入流,以字符流的形式对文件进行写操作,其构造方法有5种重载,以下是常用的几种:与FileReader类相似,FileWriter类同样需要使用缓冲流进行包装。,BufferedWriter类,BufferedWriter类可以为FileWriter类提供缓冲,其构造方法有2种重载方式,以下是常用的几种:以下是BufferedWriter类的常用方法:,FileWriter配合BufferedWriter写文件示例,public class WriterDemo public static void main(String args)throws IOException File file=new File(test.txt);/通过文件对象创建文件输出字符流对象 FileWriter fw=new FileWriter(file);/将文件输出字符流包装成缓冲流 BufferedWriter bw=new BufferedWriter(fw);bw.write(大家好!);bw.write(我正在学习Java。);bw.newLine();/换个新行 bw.write(请多多指教。);bw.newLine();/换新行 bw.write(L);bw.close();/关闭流 fw.close();/关闭流,PrintWriter类,PrintWriter类称为打印写入流,向文本输出流打印对象的格式化表示形式,它能够用于将字节的输出流转成字符的输出流。其构造方法有8种重载,以下是常用的几种:,PrintWriter类的常用方法,java.io.PrintWriter,PrintWriter是字符输出流,它提供格式化的输出功能,由于构造方法的支持,允许将字节流转化成字符流的形式;它的构造方法共有8种重载,以下是常用的几种:,PrintWriter的常用方法,PrintWriter使用注意事项,PrintWriter可以不配合BufferedWriter类一起使用。如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,否则不能完成自动刷新的功能。,从控制台接受输入,System.in的read方法可以从控制台接受输入;但由于in实际上是一个InputStream类的对象,它只能以字节形式接收数据,并且一次只能接受一个字节,这使输入操作很不便;必须将System.in进行处理,才可以顺利地从控制台接受输入,这将使用到:InputStreamReader类BufferedReader类,转换和包装System.in,InputStreamReader类用于将InputStream类型的字节输入流对象转换成Reader类型的字符读取流对象;其构造方法有4种重载方式,常用的如下:可以使用它来转换System.in,如:InputStreamReader isr=new InputStreamReader(System.in);这样的字符流效率很低,再使用BufferedReader类来为其建立缓冲,如:BufferedReader br=new BufferedReader(isr);这样,就可以从控制台接受输入了。,从控制台接受输入示例,public class ConsoleInputDemo public static void main(String args)throws IOException/将System.in转化成字符流对象 InputStreamReader isr=new InputStreamReader(System.in);/用缓冲流进行包装 BufferedReader br=new BufferedReader(isr);System.out.println(请输入您的姓名:);String name=br.readLine();/接受输入 System.out.println(请输入您的年龄:);int age=Integer.parseInt(br.readLine();/接受输入 System.out.println(您的姓名:+name);System.out.println(您的年龄:+age);br.close();/关闭流 isr.close();/关闭流,从控制台输入并写入到文件示例,/*本例从控制台接受输入,然后写入到文件中,直到用户输入!为止*/File file=new File(input.txt);/创建文件对象if(!file.exists()/判断该文件是否存在,如果不存在则创建新文件 file.createNewFile();FileWriter fr=new FileWriter(file);/针对文件对象创建文件写入流对象BufferedWriter bw=new BufferedWriter(fr);/为文件写入流建立缓冲流/将控制台输入对象转化成字符流,并建立缓冲流BufferedReader bin=new BufferedReader(new InputStreamReader(System.in);String str=bin.readLine();/接受从控制台输入的一行字符串while(!(str.equals(!)/如果输入!则代表输入结束 bw.write(str);/将从控制台输入的字符串写入到文件中 bw.newLine();/换新行 str=bin.readLine();/再从控制台接受输入/关闭所有已经打开的流bw.close();fr.close();bin.close();,对象的序列化 1,将对象转换为字节流保存起来,并在日后还原这个对象,这种机制叫做对象序列化。序列化的过程就是对象写入字节流和从字节流中读取对象java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的“深克隆”,即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。一个对象要想能够实现序列化,必须实现Serializable接口Java引入对象串行化上是为了实现两个特性:Java Beans和RMI,对象序列化 2,当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。ObjectInputStreamObjectOutputStream,NIO缓冲器Buffer类,新I/O通过使用Buffer读写数据避免了资源浪费。Buffer对象是线性的,有序的数据集合。每个Buffer有以下的属性,NIO缓冲器Buffer类,Buffer提供了改变以上三个属性的方法,NIO通道Channel接口,Channel表现了一个可以进行IO操作的通道(比如,通过FileChannel,我们可以对文件进行读写操作)。java.nio.channels包含了文件系统和网络通讯相关的channel类。这个包通过Selector和SelectableChannel这两个类,还定义了一个进行异步(non-blocking)IO操作的API,这对需要高性能IO的应用非常重要。Channel中只有两个方法:isOpen():判断此通道是否处于打开状态。close():关闭此通道,NIO字符集Charset类,Java.nio.charset.Charset处理了字符转换问题。此类定义了用于创建解码器和编码器以及获取与 charset 关联的各种名称的方法,它通过构造CharsetEncoder和CharsetDecoder将字符序列转换成字节和逆转换。,NIO选择器Selector类,在过去的阻塞I/O中,我们一般知道什么时候可以向stream中读或写,因为方法调用直到stream准备好时返回。但是使用非阻塞通道,我们需要一些方法来知道什么时候通道准备好了。在NIO包中,设计Selector就是为了这个目的。SelectableChannel可以注册特定的事件,而不是在事件发生时通知应用通道跟踪事件。然后,当应用调用Selector上的任意一个selection方法时,它查看注册了的通道看是否有任何感兴趣的事件发生。,附录:IO流的继承体系,字节输入流,附录:IO流的继承体系,附录:IO流的继承体系,附录:IO流的继承体系,Writer,BufferedWriter,字符输出流,CharArrayWriter,StringWriter,PipedWriter,PrintWriter,OutputStreamWriter,FileWriter,总结1,java.io包是Java内置的包,其中包含一系列对输入/输出进行操作的类;File类的对象可以访问文件(或目录)的属性,但不可以进行读/写操作;从方向上讲,流分为输入流和输出流,但从格式上区分的话,流分为字节流和字符流;使用FileInputStream类和FileOutputStream类以字节流方式对文件进行读/写操作,这是操作文件最基本的两个类;,总结2,FileReader类和FileWriter类配合BufferedReader类和BufferedWriter类可以以字符流方式对文件进行读/写操作;从控制台接受输入要使用到InputStreamReader类和BufferedReader类;PrintWriter能够自动刷新,并且通过print和println方法输出各种不同的数据绝大部分的IO操作都可能抛出IOException。,作业:,编写一个程序来模拟DOS命令的实现:cd,dir,md,copy,rename,delete 的实现;编写一个方法来实现输出该文件夹下面的所有的文件(包含子文件夹)结合Swing程序,完善“记事本”程序,