Java输入输出系统.ppt
7 Java输入输出系统内容n什么是流n流的分类n字节流,字符流,处理流n文件IO操作n文件类Filen标准输入输出n对象的序列化什么是流?StreamStreamStreamStreamA stream is a path ofinformation from a source to a destination.doc.txt什么是流?n程序设计语言借用水流、电流等概念,将流动的数据称为“流”。n流可以有各种来源和目的地,如标准输入输出、文件、网络等,也可以有各种不同的用途和处理方法,因而有许多分类。nJava关于流的设计思想是:提供各种不同的流类,由程序员进行组合使用,以提供最大的灵活性。流的功能概述Java提供了不同的流类以实现如下的功能n标准输入输出n文件输入输出n文本文件/二进制文件n顺序读写/随机读写njava.nio包进一步提供了异步数据读写、内存映射文件、文件锁等功能n网络数据读写n将对象存储为流/从流中读取对象,称为对象的序列化或串行化(Serialization)流的分类java.io包提供了多个流类来实现输入输出功能:n按照数据流的方向不同分为输入流和输出流n按照处理数据单位的不同分为字节流和字符流n按照功能不同可以分为节点流和处理流(或者称过滤流,Filter)流的分类InputStreamOutputStreamReaderWriterByte StreamsCharacter Streams读写以字节为单位进行 读写以字符为单位进行 流的分类n节点流(node stream)对指定的地方(磁盘文件、内存 等)读/写n处理流(filter stream)一个处理流使用节点流作为输入或输出。目的地数据源InputStream的分类nInputStream是字节输入流。它的几种输入源可以是:1.一个字节数组2.一个文件3.一个管道InputStream的分类n常用的InputStream流有下列几个:n ByteArrayInputStream n FileInputStreamn PipedInputStream/把字节数组转换为输入流/从文件中读取数据/连接一个PipedOutputStreamInputStream的方法nInputStream的常用方法:public abstract int read()throws IOException public int read(byte data)throws IOException public int read(byte data,int offset,int length)throws IOException public long skip(long n)throws IOException public int available()throws IOException public void close()throws IOException public void mark(int readlimit)public void reset()throws IOException public boolean markSupported()OutputStream的分类nOutputStream是字节输出流。它的几种输出目的地可以是:1.一个字节数组2.一个文件3.一个管道OutputStream的分类n常用的OutputStream流有下列几个:nByteArrayOutputStreamnFileOutputStreamnPipedOutputStreamOutputStream的方法nOutputStream的常用方法:public abstract void write(int b)throws IOException public void write(byte data)throws IOException public void write(byte data,int offset,int length)throws IOException public void flush()throws IOExceptionpublic void close()throws IOException 字节流示例nTestFileInputStream.javanTestFileOutputStream.javaReader&Writer的分类nReader&Writer的分类类似于InputStream和OutputStream的分类。n所以下面我们通过一个表格来做对比,从而对Reader&Writer的分类加以介绍。Reader&Writer的分类InputStream ReaderConverter:InputStreamReaderOutputStreamWriterConverter:OutputStreamWriterFileInputStreamFileReaderFileOutputStreamFileWriterStringBufferInputStreamStringReader(无对应)StringWriterReader&Writer的分类ByteArrayInputStream CharArrayReader ByteArrayOutputStreamCharArrayWriterPipedInputStreamPipedReader其中,InputStreamReader将一个字节流转换为字符流来读入;OutputStreamWriter将一个字符流转换为字节流写出字符流示例nTestFileReader.javanTestFileWriter.java什么是处理流?nFilter(处理流/过滤流)是建立在其他流的基础上的。例如:InputSteam/System.inInputStreamReaderBufferedReader处理流的分类n各种处理流实现不同的过滤,有的可以暂存数据,有的可以统计经过的数据,有的可以转换数据类型。nFilter的分类n面向字节的Filtern面向字符的Filter处理流(面向字节)nFilterInputStream和FilterOutputStream.nFilterInputStream和FilterOutputStream都是抽象类,分别继承自InputStream 和 OutputStreamn根据实现过滤功能的不同,面向字节的Filter也分成 不同的类别,下表给出它们的分类。处理流(面向字节)详细分类FilterOutputStream FilterInputStreamPrintStream/用于产生格式化输出BufferedOutputStream/利用缓冲区来提高写效率BufferedInputStream/利用缓冲区来提高读效率DataOutputStream/与DataInputStream搭配使用,可以按照与平台无关的方式向流中写基本类型(int、char和long等)的数据DataInputStream/与DataOutputStream搭配使用,可以按照与平台无关的方式从流中读取基本类型(int、char和long等)的数据处理流(面向字符)nFilterReader和FilterWriter.n根据实现过滤功能的不同,面向字符的Filter也分成不同的类别。下表给出它们的分类。处理流(面向字符)详细分类FilterReader FilterWriterPushBackReader PrintWriterBufferedReaderBufferedWriterLineNumberReader处理流示例nTestBufferedStream1.javanTestBufferedStream2.java文件I/O文件I/O 相关类nFileInputStreamnFileOutputStreamnFileReadernFileWriternDataInputStream/DataOutputStreamnRandomAccessFile二进制数据访问nJava利用DataInputStream/DataOutputStream来访问二进制数据,例如访问二进制数据文件。nDataInputStream/DataOutputStream提供读取和写入基本数据类型以及字符串类型数据的能力nDataInputStream/DataOutputStream的方法(参见API文档)n示例:TestDataStream.java文件的随机访问nJava利用RandomAccessFile类来实现随机访问n随机访问文件方式可以在指定位置读/写字节内容nRandomAccessFile同时具有DataInputStream和DataOutputStream的功能n提供方法void seek(long pos)指定位置,以便读写数据n示例:TestRandomAccessFile.java更多例子例1:文件I/O 举例n下面这个程序FileIO.java演示文件读写操作。n在这个例子中,假设在程序当前执行目录下已经存在一个文件in.txt(它的格式如图1),FileIO.java程序读取in.txt这个文件,然后生成一个新的文件out.txt(生成的新文件out.txt的格式如图2)。例1:文件I/O 举例in.txt文件格式如图1:firstsecondthirdforthfifthsixthseventh图1line 1=firstline 2=secondline 3=thirdline 4=forthline 5=fifthline 6=sixthline 7=seventh图2out.txt文件格式如图2:1.try2.BufferedReader in=new BufferedReader(new FileReader(in.txt);3.PrintWriter out=new PrintWriter(4.new BufferedWriter(5.new FileWriter(out.txt);6.String s;7.int i=1;8.while(s=in.readLine()!=null)9.out.println(line+i+=+s);10.i+;11.12.in.close();13.out.close();14.catch(FileNotFoundException e)15.System.err.println(cannot open in.txt);16.catch(IOException e)17.System.err.println(I/O exception);18.FileIO.java 代码例1:文件I/O 举例firstsecondthirdforthfifthsixthseventhline 1=firstline 2=secondline 3=thirdline 4=forthline 5=fifthline 6=sixthline 7=seventh正确运行后例1:文件I/O 举例n如果在当前目录下没有in.txt文件,则运行返回结果如下:例2:DataOutputStream举例n这个例子使用DataOutputStream过滤流,生成一个文件。Stream1.import java.io.*;2.public class DataIODemo3.public static void main(String args)4.try5.DataOutputStream out=new DataOutputStream(6.new FileOutputStream(text.dat);7.double prices=6.55,9.99,1.8,2.33,0.90;8.int units=12,9,5,6,7;9.String descs=chicken,beef,lettuce,potato,tomato;10.for(int i=0;iprices.length;i+)11.out.writeDouble(pricesi);out.writeChar(t);12.out.writeInt(unitsi);out.writeChar(t);13.out.writeChars(descsi);out.writeChar(n);14.15.out.close();16.catch(IOException e)17.18.DataIODemo.java例3:DataInputStream举例这个例子使用DataInputStream过滤流。读取例2生成的文件。Stream1.import java.io.*;2.public class DataIODemo23.public static void main(String arg)4.DataInputStream in=null;5.try6.in=new DataInputStream(new FileInputStream(text.dat);7.double price,total=0.0;8.int unit;char ch;StringBuffer desc;9.while(true)10.price=in.readDouble();in.readChar();11.unit=in.readInt();in.readChar();12.desc=new StringBuffer(20);13.while(ch=in.readChar()!=n)14.desc.append(ch);15.total=price*unit;16.System.out.println(you ordered:+desc 17.+t+price+*+unit+=+total);18.19.DataIODemo2.java接上页20.catch(EOFException e)21.try22.in.close();23.catch(IOException e1)24.25.catch(IOException e)26.27.DataIODemo2.javaFile类n类 n提供文件与目录的各种有用信息nFile类并不打开文件,也不处理文件内容n例:File f1=new File(/etc/passwd);File f2=new File(/etc,passwd);nFile类的对象经常作为文件流类构造方法的参数File类n通过方法 exists()判断文件或路径是否存在n创建了类File的实例对象,并不等价于在硬盘上创建该文件nFileOutputStream在删除文件内容时,没有警告信息nFile的实例对象可以判断出文件是否存在,提供警告信息,或改变打开文件方式路径或文件名中的分隔符n分隔符n分隔路径中的目录名、子目录名以及文件名n/(Unix)或 (Windows)n这两种分隔符Java均可以识别n在字符串常量中用/或n最正规的方法是使用File.separator静态字段File类示例nTestFile.java格式化文本输出n格式化文本输出类:nPrintStream和PrintWritern前者将所有字符按照平台默认的字符编码转换为字节,后者直接写入字符n这两个类提供了print(),println(),printf()等常用方法以方便格式化输出n这两个类的一个重要特点是输出时不抛出IOExceptionn示例:nTestPrintStream1.java/TestPrintStream2.java标准输入输出n标准输入默认是指从键盘输入,Java用System.in来指向系统的标准输入nSystem.in的类型是InputStream,其重要的方法是read()n现在更方便的做法是使用Scanner类n由于历史的原因,System.out的类型是PrintStream,而不是PrintWriter,其重要方法有print()、println()、write()、flush()等如何读取文本文件中的数据n如果不必按行分析,可直接使用Scannern如果需要按行分析数据,且每行的数据不一样多,可利用BufferedReader套在FileReader上,利用前者的readLine()读取一行,然后利用所读取的一行字符串构造Scanner对象进行处理;或者用String类的split()方法分解这一行,然后用各个基本数据类型封装类的ParseXxx()方法进行转换n也可以使用Scanner的nextLine()方法,读取一行,然后对这一行作上述的分析小专题实验n假设文本文件abc1.txt中有一些数据,分为若干行,每行有一些个数不等的整数,用空格隔开。写一个程序读入该文件中的数据,对每行数据从小到大进行排序,然后按行输出到文本文件abc2.txt中,输出的文件中数据的格式与输入文件相同。12 35 77 451 2 3 4 5 67 912 11 8 9 01-112 3 4 5 6 7 8 9 0-4 5-15 4 3 2 1 6 713 34 56 78 99 9811 111 11 11 11文件IO小结n二进制数据输入输出,用DataInputStream/DataOutputStreamn(二进制)随机文件读写,用RandomAccessFilen文本数据格式化输出,用PrintWritern文本数据输入,可以用Scanner类,或者用BufferedReader读入一行,然后用String类的split()方法分解这一行,然后用各个基本数据类型封装类的ParseXxx()方法进行转换*综合示例nTextFileTest.javanRandomFileTest.java对象序列化nJava提供一种机制,能够将内存中存在的对象转化为流,以便保存到文件中,或者通过网络进行传输等等。这种机制称为序列化。nJava利用ObjectInputStream类和ObjectOutputStream类创建对象输入流和对象输出流。对象输出流使用writeObject(Object obj)方法将一个对象obj写入输出流送往目的地,对象输入流使用readObject()从源中读取一个对象到程序中。nObjectInputStream类和ObjectOutputStream类的构造方法分别是:ObjectInputStream(InputStream in),ObjectOutputStream(OutputStream out)。Serializable接口n一个类的对象若要进行序列化,必须实现Serializable接口。nSerializable接口没有任何方法,是一个标记接口(JDK5.0以后,要求实现了Serializable接口的类提供一个serialVersionUID静态字段,否则会给出一个编译警告)。n序列化和反序列化的过程由Java实现,使用者可以不必了解其细节。简单示例nTestObjectIO.javatransient关键字和Externalizable接口ntransient(瞬时的,短暂的)用来修饰成员变量,控制该成员变量不参与序列化。nExternalizable接口是Serializable的子接口,凡是实现了该接口的类,可以自行定义如何实现序列化和反序列化的过程,而不是使用Java的实现。复杂示例nObjectStreamTest.java*Zip文件流nZipTest.java