Java输入输出流.ppt
Java输入输出流,伍淳华北京邮电大学计算机学院,Java,输入输出流,文件描述,类File提供了一种与机器无关的方式来描述一个文件对象的属性文件的生成 public File(String path);public File(String path,String name);public File(File dir,String name);,Java,Java输入输出流,文件描述,文件名的处理 String getName();/*得到一个文件的名称(不包括路径)*/String getPath();/得到一个文件的路径名 String getAbsolutePath();/*得到一个文件的绝对路径名*/String getParent();/*得到一个文件的上一级路径名*/String renameTo(File newname);/*将当前文件名更名为给定文件的完整路径*/,Java,Java输入输出流,文件描述,文件属性测试 boolean exists();/*测试当前File对象所指向的文件是否存在*/boolean canWrite();/测试当前文件是否可写 boolean canRead();/测试当前文件是否可读 boolean isFile();/*测试当前文件是否是文件(不是目录)*/boolean isDirectory();/*测试当前文件是否是目录*/,Java,Java输入输出流,文件描述,普通文件信息和工具 long lastModified();/得到文件最近一次修改的时间 long length();/得到文件的长度,以字节为单位 boolean delete();/删除当前文件目录操作 boolean mkdir();/*根据当前对象生成一个由该对象指定的路径*/string list();/列出当前目录下的文件,Java,Java输入输出流,import java.io.*;class FileTestWpublic static void main(String args)System.out.println(“Path separator”+File.pathSeparator);System.out.println(“Path separator char”+File.pathSeparatorChar);System.out.println(“File separator”+File.separator);System.out.println(“File separator char”+File.separatorChar);File f=new File(“dong1/test1.class”)System.out.println();System.out.println(f);System.out.println(“exist?”+file.exists();System.out.println(“name”+f.getName();System.out.println(“path”+f.getPath();System.out.println(“absolute path”+f.getAbsolutePath();System.out.println(“parent”+f.getParent();,Java,Java输入输出流,System.out.println(“is a File”+f.isFile();System.out.println(“is a directory”+f.isDirectory();System.out.println(“length”+f.length();System.out.println(“can read”+f.canRead();System.out.println(“can Write”+f.canWrite();System.out.println(“last modified”+f.lastModified();File newF=new File(“new File”);System.out.println(“reName”+f+”);f.renameTo(newF);System.out.println(“name”+newF.getName();System.out.println(f+“exists?”+f.exists();System.out.println(“delete”+newF+”);newF.delete();System.out.println(newF+“exists?”+newF.exists();,Java,Java输入输出流,运行结果,path separator;path separator char;file separatorfile separator chardong1/test1.classexists?truenametest1.classpath/dong1/test1.classabsolute path/dong1/test1.classparent/dong1is a File?trueis a directory?false,Java,Java输入输出流,运行结果,length 514can read truecan write truelast modified 907117020000rename/dong1/test1.classname newFile/dong1/test1.class exists?falsedelete newFilenewFile exists?false,Java,Java输入输出流,文件处理,列出目录中与某种模式相匹配的文件 public string list(FilenameFilter filter);在接口FilenameFilter中定义的方法只有:boolean accept(File dir,String name);,Java,Java输入输出流,import java.io.*;public class FileFilterTest public static void main(String args)File dir=new File(“/dong1”);Filter filter=new Filter(“htm”);System.out.println(“list html files in directory”+dir);String files=dir.list(filter);for(int i=0;ifiles.length;i+)File f=new File(filesi);if(f.isFile()System.out.println(“file”+f);else System.out.println(“sub directory”+f);,Java,Java输入输出流,class Filter implements FilenameFilterString extent;Fileter(String extent)this.extent=extent;public boolean accept(File dir,String name)return name.endsWith(“.”+extent);,Java,Java输入输出流,运行结果,list html files in derectory/dong1 file cert_test.htm file cert_sample.htm file cert_obj.htm,Java,流的基本概念,Java语言中输入/输出功能是通过流类来实现的,可以完成从基本的输入/输出到复杂的随机文件访问,包括Java中的网络操作也是通过流来完成的。,文件,程序,文件,程序,网络端点,数据流,起点,终点,网络端点,Java,流的基本概念,数据流是从源到目的的字节的有序序列,先进先出。按照流相对于程序的方向,可以分为两种基本流:Input stream(输入流),Output stream(输出流),Java,输入流与输出流,输入流:用于将程序中需要的数据从键盘、文件等外部设备读入。输出流:用于将程序中产生的数据写到文件、屏幕显示等输出设备上,读操作过程:打开一个流while(是否有更多数据)读数据关闭流,写操作过程:打开一个流While(是否有更多数据)写数据关闭流,Java,流式输入输出的特点,每个数据都必须等待排在它前面的数据读入或送出之后才能被读写每次读写操作处理的都是序列中剩余的未读写数据中的第一个,而不能随意选择输入输出的位置,Java,Java的标准输入输出,标准输入输出是指在命令行方式下的输入输出方式。Java通过System.in、System.out和System.err来实现标准输入输出和标准错误输出。每当main方法被执行时,就自动生成System.in、System.out和System.err三个对象。,Java,Java的标准输入输出,System.in是字节输入流InputStream类的一个对象,其中有read方法从键盘读入数据:public int read()throws IOException public int read(byte b)throws IOExceptionSystem.out是流PrintStream类的一个对象,其中print和println方法向屏幕输出数据。System.err是流PrintStream类的一个对象,用于向屏幕输出错误信息。,Java,例1:输入输出的实例,import java.io.IOException;public class StdinOut public static void main(String args)byte buf=new byte100;int count=0;System.out.println(Please input a string:);trycount=System.in.read(buf);catch(IOException e)e.printStackTrace();System.out.println(count=+count);for(int j=0;j count;j+)System.out.println(char)bufj);System.out.println(Input ten chars);int ch;tryfor(int i=0;i 10;i+)ch=System.in.read();System.out.println(char)ch);catch(IOException e)e.printStackTrace();,Java,例1:输入输出的实例,程序,控制台,InputStream,PrintStream,Java,Java的数据流,Java的数据流都在java.io包里Java的数据流根据操作的数据流分为字节流和字符流字节流:流中的数据以8位字节为单位进行读写,以InputStream和OutputStream为基础类。字符流:流中的数据以16位字节为单位进行读写,以Reader和Writer为基础类。,Java,Java的数据流,以字节为对象:输入流:InputStream 输出流:OutputStrea以字符为对象:输入流:Reader 输出流:Writer,字节流和字符流的比较,字节流适用于各类文件每次读写8位字节效率较低,字符流适用于16位的字符文件每次读写16位字符效率较高,Java,字节流,InputStream和OutputStream分别是字节输入流和字节输出流的超类InputStream和OutputStream是抽象类InputStream和OutputStream提供许多用于字节输入输出的方法,包括:数据的读取数据的写入标记位置获取数据量关闭数据流,Java,字节输入流InputSream类的层次结构,Java,InputStream 方法,三个基本read()方法int read()/读一个字节返回int read(byte)/将数据读入byte,返回读的字节数int read(byte,int offset,int length)其它方法void close()/关闭流。int available()/返回未读的字节数long skip(long n)/跳过n个字节,Java,字节输出流OutputSream类层次,Java,OutputStream方法,三个基本的write()方法void write(int)/写一个字节void write(byte)/写一个字节数组void write(byte,int offset,int length)其它方法void close()void flush()/强行写,Java,字节文件输入输出流,FileInputStream和FileOutputStream实现了对文件的顺序访问,以字节为单位对文件进行读写操作,主要有这样几步:创建文件输入输出流的对象打开文件用文件读写方法读写数据关闭数据流。,Java,创建文件输入流对象并打开文件,创建FileInputStream的对象,打开要读取数据的文件 FileInputStream的构造方法是:public FileInputStream(String name)throws FileNotFoundExceptionpublic FileInputStream(File file)throws FileNotFoundException如下面语句可以创建文件的输入流对象,并打开要读取数据的文件d:javapro1.java:FileInputStream rf=new FileInputStream(“d:/java/pro1.java”);,Java,创建文件输出流并打开文件,创建FileOutputStream的对象,打开要写入数据的文件FileOutputStream的构造方法是:public FileOutputStream(String name)throws FileNotFoundExceptionpublic FileOutputStream(String.name,Boolean append)throws FileNotFoundExceptionpublic FileOutputStream(File file)throws FileNotFoundException 其中:name是要打开的文件名,file是文件类File的对象。如下面语句可以创建文件的输出流对象,并打开要写入数据的文件d:/java/pro2.java:FileOutputStream wf=new FileOutputStream(“d:/java/pro2.java”);,Java,对文件进行读写的方法,用read方法读取文件的数据 public int read()throws IOException/返回从文件中读取的一个字节。public int read(byte b)throws IOException public int read(byte b,int off,int len)throws IOException/返回读取的字节数,若b的长度为0,返回0。,Java,对文件进行读写的方法,用write方法将数据写入文件public void write(int b)throws IOException 向文件写入一个字节,b是int类型,所以将b的低8位写入public void write(byte b)throws IOExceptionpublic void write(byte b,int off,int len)throws IOException 将字节数组写入文件,其中off是b中的起始位置,len是写入的最大长度。,Java,字节文件流的关闭,当读写操作完毕时,要关闭输入或输出流,释放相关的系统资源。如果发生I/O错误,抛出IOException异常。关闭数据流的方法是:public void close()throws IOException,Java,读取文件内容并显示在屏幕,import java.io.*;public class FileIn public static void main(String args)try FileInputStream rf=new FileInputStream(D:/java/file1.txt);int b;while(b=rf.read()!=-1)System.out.print(char)b);rf.close();catch(IOException ie)System.out.println(ie);catch(Exception e)System.out.println(e);,Java,复制文件,import java.io.*;public class FileIn_Out public static void main(String args)try FileInputStream rf=new FileInputStream(D:/java/file1.txt);FileOutputStream wf=new FileOutputStream(D:/java/file2.txt);byte b=new byte512;while(rf.read(b,0,512)!=-1)wf.write(b);rf.close();wf.close();catch(IOException ie)System.out.println(ie);catch(Exception e)System.out.println(e);,Java,Java,Java输入输出流,节点流,节点流指的是与存储介质直接相关的流,例如FileInputStream,StringReader等。,Java,Java,Java输入输出流,过滤流,过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果。类FilterInputStream和FilterOutStream分别作为所有过滤输入流和输出流的父类。,Java,Java,Java输入输出流,过滤流,为了使用一个过滤流,首先必须把过滤流连接到某个输入/输出上,通常通过在构造方法的参数中指定所要连接的输入/输出流来实现。例如:FilterInputStream(InputStream in);FilterOutputStream(OutputStream out);,Java,Java,Java输入输出流,过滤流,BufferedInputStream和BufferOutputStream缓冲流,用于提高输入/输出处理的效率。java.long.Object|+-java.io.InputStream|+-java.io.FilterInputStream|+-java.io.BufferedInputStream,Java,数据输入输出流,数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。DataInputStream(InputStreamin)数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。DataOutputStream(OutputStreamout),Java,DataInputStream方法 byte readByte()boolean readBoolean()long readLong()char readChar()double readDouble()float readFloat()short readshort()int readInt()String readUTF(),数据输入输出流,Java,DataOutputStream 方法 void writeByte(byte)void writeBoolean(boolean)void writeLong(long)void writeChar(char)void writeDouble(double)void writeFloat(float)void writeshort(short)void writeInt(int)void writeBytes(String)void writeChars(String)void writeUTF(Stringstr),数据输入输出流,Java,数据流示例:DataIOTest.java,import java.io.*;public class DataIOTest public static void main(String args)throws IOException DataOutputStream out=new DataOutputStream(new FileOutputStream(invoice1.txt);FileOutputStream f=new FileOutputStream(invoice1.txt);DataOutputStream out=new DataOutputStream(f);double prices=19.99,9.99,15.99,3.99,4.99;int units=12,8,13,29,50;String descs=Java T-shirt,Java Mug,Duke Juggling Dolls,Java Pin,Java Key Chain;for(int i=0;i prices.length;i+)out.writeDouble(pricesi);out.writeChar(t);out.writeInt(unitsi);out.writeChar(t);out.writeChars(descsi);out.writeChar(n);out.close();,Java,DataInputStream in=new DataInputStream(new FileInputStream(invoice1.txt);double price;int unit;String desc;double total=0.0;try while(true)price=in.readDouble();in.readChar();/throws out the tab unit=in.readInt();in.readChar();/throws out the tab desc=in.readLine();System.out.println(Youve ordered+unit+units of+desc+at$+price);total=total+unit*price;catch(EOFException e)System.out.println(For a TOTAL of:$+total);in.close();,数据流示例:DataIOTest.java,Java,Java输入输出流,管道流,管道用来把一个程序,线程或者代码块的输出连接到另一个程序,线程或者代码块的输入管道输入流作为一个通信管道的接收端,管道输出流作为发送端在使用管道之前,管道输出流和管道输入流之间必须进行连接,Java,Java输入输出流,管道流,在构造方法中连接:PipeInputStream(PipeOutputStream des);PipeOutputStream(PipeInputStream src);用connect方法进行连接 类PipeInputStream中定义为:void connect(PipeOutputStream des);类PipeOutputStream中定义为:void connect(PipeInputStream src);,Java,Java输入输出流,内存的读写,ByteArrayInputStream 8位ByteArrayOutputStream 8位StringBufferInputStream 16位,Java,Java输入输出流,顺序输入流,SequenceInputStream 把几个输入流顺序连接起来,Java,Java输入输出流,import java.io.*;Public class SequenceTestFileInputStream fs1,fs2;String s;try try fs1=new FileInputStream(“text1”);fs1=new FileInputStream(“text2”);catch(FileNotFoundException e)System.out.println(“File not found or permission denied”);System.exit(-1);,Java,Java输入输出流,SequenceInputStream s1=new SequenceInputStream(fs1,fs2);while(s=s1.readLine()!=null)System.out.println(s);catch(IOException e)System.out.println(“error”+e);System.exit(-2);,Java,字符流,类Reader是字符输入流的抽象超类,其提供的方法与InputStream类似,只是将基于Byte的参数改为基于Char。类Writer是字符输出流的抽象超类,其提供的方法与OutputStream类似,只是将基于Byte的参数改为基于Char。Reader和Writer 类实现字节和字符间的自动转换。每一个核心输入、输出流,都有相应的Reader和Writer版本。,Java,Reader的类层次结构,Java,Reader的基本方法,int read();/读单个字符int read(char cbuf);/读字符放入数组中int read(char cbuf,int offset,int length);/读字符放入数组的指定位置 void close()/关闭流。long skip(long n)/跳过n个字符boolean ready()/测试当前流是否准备好进行读,Java,Writer的类层次结构,Java,Writer的基本方法,int write(int c);/写单个字符int write(char cbuf);/写字符数组int write(char cbuf,int offset,int length);int write(String str);int write(String str,int offset,int length);void close()void flush()/强行写,Java,字符文件输入输出流,FileReader和Filewriter类用于字符文件的输入和输出读写文件的过程:先创建对象打开文件然后用读写方法从文件中读取数据或将数据写入文件最后关闭数据流。,Java,创建字符流文件对象,创建FileReader或Filewriter对象,打开要读写的文件FileReader的构造方法是:public FileReader(String filename)public FileReader(File file)FileWriter的构造方法是:public FlieWriter(String filename)public Filewriter(File file),Java,字符文件流的读写,用从超类继承的read和write方法可以对打开的文件进行读写。读取文件数据的方法:int read()throws IOException int read(char b)throws IOException int read(char b,int off,int len)throws IOException数据写入到文件的方法:void write(char b)throws IOException void write(char b)throws IOException void write(char b,int off,int len)throws IOException,Java,字符文件流的关闭,对文件操作完毕要用close方法关闭数据流。public void close()throws IOException,Java,从键盘输入一行文字,写入文件file3.txt中,import java.io.*;public class FilecharOut public static void main(String args)char c=new char512;byte b=new byte512;int n,i;try FileWriter wf=new FileWriter(file3.txt);n=System.in.read(b);for(i=0;in;i+)ci=(char)bi;wf.write(c);wf.close();catch(IOException e)System.out.println(e);,Java,字符缓冲流,BufferedReader和BufferedWriter类以缓冲区方式对数据进行输入输出。BufferedReader用于字符缓冲输入,构造方法如下:public BufferedReader(Reader in)public BufferedReader(Reader in,int sz)其中:in为超类Reader的对象,sz为用户设定的缓冲区大小。,Java,Bufferedwriter用于字符缓冲流输出,构造方法为:public BufferedWriter(Writer out)public Bufferedwriter(Writer out,int sz)其中:out为超类Writer的对象,sz为用户设定的缓冲区大小。,字符缓冲流,Java,例6:从键盘输入文字存入文件,再读出加上行号后打印在屏幕,import java.io.*;public class BufferDemo public static void main(String args)String f=f.txt;String str=;int i=0;try BufferedReader keyIn=new BufferedReader(new InputStreamReader(System.in);BufferedWriter bw=new BufferedWriter(new FileWriter(f);BufferedReader br=new BufferedReader(new FileReader(f);System.out.println(Please input file text:);while(!(str=keyIn.readLine().equals(exit)bw.write(str,0,str.length();bw.newLine();,字符缓冲流,Java,bw.close();while(str=br.readLine()!=null)i+;System.out.println(i+:+str);catch(IOException e),字符缓冲流,Java,Java输入输出流,对象的串行化(Serialization),对象记录自己的状态以便将来再生的能力,叫做对象的持续性(persistence)对象通过写出描述自己状态的数值来记录自己,这个过程叫做对象的串行化(Serialization),Java,Java输入输出流,串行化方法,在java.io包中,接口Serializable用来作为实现对象串行化的工具,只有实现了Serializable的类的对象才可以被串行化,Java,Java输入输出流,定义一个可串行化对象,public class Student implements Serializable int id;/学号 String name;/姓名 int age;/年龄 String department;/系别public Student(int id,String name,int age,String department)this.di=id;this.name=name;this.age=age;this.department=department;,Java,Java输入输出流,构造对象的输入/输出流,java.io包中,提供了ObjectInputStream和ObjectOutputStream将数据流功能扩展至可读写对象。在ObjectInputStream中使用readObject()可以直接读取一个对象,ObjectOutputStream中用writeObject方法可以直接将对象保存到输出流中,Java,Java输入输出流,保存对象状态,Student stu=new Student(981036,”liu ming”,18,”csd”);FileOutputStream fo=new FileOutputStream(“data.ser”);ObjectOutputStream so=new ObjectOutputStream(fo);tryso.writeObject(stu);so.close();catch(IOException e)System.out.println(e);FileInputStream fi=new FileInputStream(“data.ser”);ObjectInputStream si=new ObjectInputStream(fi);trysi.writeObject(stu);si.close();catch(IOException e)System.out.println(e);,Java,Java输入输出流,串行化的注意事项,串行化能保存的元素 只能保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符都不能保存,Java,Java输入输出流,串行化的注意事项,transient关键字 对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的,例如一个Thread对象,或者一个FileInputStream对象,对于这些字段我们必须用transient关键字标明,Java,Java输入输出流,定制串行化,缺省的串行化机制,对象串行化首先写入类数据和类字段的信息,然后按照名称的上升顺序写入其数值。如果想自己明确的控制这些数值的写入顺序和写入种类,必须定义自己的读取数据流的方式。就是在类的定义中重写readObject 和writeObject方法,Java,输入输出流类分类,Java,输入输出流类分类(续),Java,输入输出流类分类(续),Java,Java的例外处理和输入输出流,本讲小结,字符流字节流对象流节点流过滤流,Thank You!,