第8章文件、流和输入输出技术下一页上一页返回开始文件、流和输入输出技术2主要内容8.1I/O流概述什么是流8.2I/O流类I/O流的层次:字符流、字节流、标准输入/输出流8.3过滤流与流的串接8.4文件流类与文件操作8.5对象串行化总结作业下一页上一页返回开始文件、流和输入输出技术38.1I/O流概述输入/输出处理是程序设计中非常重要的一部分,比如从键盘读取数据、从文件中读取数据或向文件中写数据等等。Java把这些不同类型的输入、输出源抽象为流(stream),用统一接口来表示,从而使程序简单明了。Jdk提供了包java.io,其中包括一系列的类来实现输入/输出处理。进行I/O操作时可能会产生I/O异常,属于非运行时异常,应该在程序中处理。如:FileNotFoundException,EOFException,IOException下一页上一页返回开始文件、流和输入输出技术4什么是流流实际上是一个数据序列。采用流的机制可以使数据有序地输入和输出。输入流与输出流。输入流数据input类数据源Java程序读输入流输出流数据output类接收器Java程序写输出流下一页上一页返回开始文件、流和输入输出技术58.2I/O流类Java有各种各样的执行I/O的流,在java.io包中定义了这些流,其层次结构图如图8.3所示(P192)。编写程序时,java.io包必须被执行输入输出的程序导入。输入输出流可以从以下几个方面进行分类:从流的方向划分:输入流和输出流;从流的分工划分:节点流(从特定的地方读写的流类,例如:磁盘或一块内存区域)和处理(过滤)流(使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的);从流的内容划分:面向字符的流和面向字节的流。下一页上一页返回开始文件、流和输入输出技术68.2.1字符流Java中的字符使用的是Unicode编码,每个字符占有两个字节,即16bit。字符流是以16位的Unicode码表示的字符为基本处理单位,进行文本数据的读写,可以实现Java程序中的内部格式和文本文件、显示输出、键盘输入等外部格式之间的转换。Reader和Writer是java.io包中所有字符流的抽象基类。提供了输出字符的API及其部分实现。1.ReaderReader类是处理所有字符流输入类的父类。主要有以下方法:下一页上一页返回开始文件、流和输入输出技术7读取字符publicintread()throwsIOException;/*读取一个字符,返回值为读取的字符*/publicintread(charcbuf[])throwsIOException;/*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/publicabstractintread(charcbuf[],intoff,intlen)throwsIOException;/*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/下一页上一页返回开始文件、流和输入输出技术8标记流publicbooleanmarkSupported();/*判断当前流是否支持做标记*/publicvoidmark(intreadAheadLimit)throwsIOException;/*给当前流作标记,最多支持readAheadLimit个字符的回溯。*/publicvoidreset()throwsIOException;/*将当前流重置到做标记处*/关闭流publicabstractvoidclose()throwsIOException;下一页上一页返回开始文件、流和输入输出技术9java.io包中Reader的类层次ReaderBufferedReaderCharArrayReaderFilterReaderPipedReaderStringReaderFileReaderLineNumberReaderPushbackReaderInputStreamReader下一页上一页返回开始文件、流和输入输出技术102.Writer向输出流写入字符publicvoidwrite(intc)throwsIOException;//将整型值c的低16位写入输出流publicvoidwrite(charcbuf[])throwsIOException;//将字符数组cbuf[]写入输出流publicabstractvoidwrite(charcbuf[],intoff,intlen)throwsIOException;/*将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流*/publicvoidwrite(Stringstr)throwsIOException;//将字符串str中的字符写入输出流publicvoidwrite(Stringstr,intoff,intlen)throwsIOException;/*将字符串str中从索引off开始处的len个字符写入输出流*/下一页上一页返回开始文件、流和输入输出技术11flush()刷空输出流,并输出所有被缓存的字节。关闭流publicabstractvoidclose()throwsIOException;下一页上一页返回开始文件、流和输入输出技术123.Reader与Writer的子类从Reader(直接子类6个)和Writer(直接子类7个)派生出的一系列类,这类流以16位的Unicode码表示的字符为基本处理单位。◇InputStreamReader、OutputStreamWriter◇CharArrayReader、CharArrayWriter◇PipedReader、PipedWriter◇FilterReader、FilterWriter◇BufferedReader、BufferedWriter◇StringReader、StringWriter◇PrintWriter下一页上一页返回开始文件、流和输入输出技术13java.io包中Writer的类层次WriterBufferedWriterCharArrayWriterFilterWriterPipedWriterPrintWriterFileWriterOutputStreamWriterStringWriter下一页上一页返回开始文件、流和输入输出技术148.2.2字节流字节流类是从抽象类InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。1.InputStreamInputStream类直接继承Object类。主要方法如下:下一页上一页返回开始文件、流和输入输出技术15从流中读取数据:abstractintread();//读取一个字节,返回值为所读的字节intread(byteb[]);//读取多个字节,放置到字节数组b中,通常读取的字节数量为b的长度,返回值为实际读取的字节的数量intread(byteb[],intoff,intlen);//读取len个字节,放置到以下标off开始字节数组b中,返回值为实际读取的字节的数量intavailable();//返回值为流中尚未读取的字节的数量longskip(longn);//读指针跳过n个字节不读,返回值为实际跳过的字节数量下一页上一页返回开始文件、流和输入输出技术16关闭流:close();//流操作完毕后必须关闭使用输入流中的标记:voidmark(intreadlimit);//记录当前读指针所在位置,readlimit表示读指针读出readlimit个字节后所标记的指针位置才失效voidreset();//把读指针重新指向用mark方法所记录的位置booleanmarkSupported();//当前的流是否支持读指针的记录功能测试当前流是否支持mark和reset方法下一页上一页返回开始文件、流和输入输出技术17java.io包中InputStream的类层次InputStreamStringBufferInputStreamFileInputStreamByteArrayInputStreamFilterInputStreamObjectInputStreamPipedInputStreamSequenceInputStreamLineNumberInputStreamDataInputStreamBufferedInputStreamPushbackInputStream下一页上一页返回开始文件、流和输入输出技术182.OutputStream输出数据:voidwrite(intb);//往流中写一个字节bvoidwrite(byteb[]);//往流中写一个字节数组bvoidwrite(byteb[],intoff,intlen);//把字节数组b中从下标off开始,长度为len的字节写入流中flush()//刷空输出流,并输出所有被缓存的字节由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。关闭流:close();//流操作完毕后必须关闭下一页上一页返回开始文件、流和输入输出技术19java.io包中OutputStream的类层次OutputStreamFileOutputStreamByteArrayOutputStreamFilterOutputStreamObjectOutputStreamPipedOutputStreamPrintStreamDataOutputStreamBufferedOutputStream下一页上一页返回开始文件、流和输入输出技术203.Input/OutputStream的子类◇FileInputStream、FileOutputStream◇PipedInputStream、PipedOutputStream◇ByteArrayInputStream、ByteArrayOutputStream◇ObjectInputStream、ObjectOutputStream◇FilterInputStream、FilterOutputStream◇StringBufferInputStream◇SequenceInputStream下一页上一页返回开始文件、流和输入输出技术21基本的流类FileInputStream和FileOutputStream节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。BufferedInputStream和BufferedOutputStream过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。DataInputStream和DataOutputStream过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。PipedInputStream和PipedOutputStream管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。下一页上一页返回开始文件、流和输入输出技术228.2.3标准输入/输出在Java应用程序开始执行时(也就是当main方法被执行时),Java就会自动创建3个与设备关联的流对象:System.in、System.out和System.err。System.in对象(标准输入流对象)是InputStream类型的,是连接程序与标准输入设备(通常是键盘)的一个输入流对象,当执行System.in.read()操作时,从键盘得到的信息通过System.in流到了程序中。System.out对象(标准输出流对象)是PrintStream类型的,是