Java SE 第九十一~九十六 IO详解

1.IO课件知识复习:

File类是不对称的:随眼存在允许验证一个简单文件对象属性的很多方法,但是没有相应的方法来该拜年这些属性.

File类中的常用的方法

getName();

getPath();

getAbsolutePath();

getParent()

renameTo(File name);

long length()

boolean delete()

boolean mkdir()

String[] list()

boolean exists()

boolean canWrite()

boolean canRead()

boolean isFile()

boolean isDiretory()

使用FilenameFilter:

希望能够限制由list()方法返回的文件数目,使它仅返回那些与一定的文件名方式或者过滤(filter)相匹配的文件.为了达到这样的目的,必须使用list()的第二种形式(方法重载)

String[] list(FilenameFilter FFobj)

该形式中,FFobj是一个实现FilenameFilter接口的类的对象.

FilenameFilter仅定义了一个方法,accept().该方法被列表中的每个文件调用一次,它的通常形式如下:

boolean accept(File directory,String filename)

当被directory指定的目录中的文件(也就是说,那些与filename参数匹配的文件)包含在列表中时,accept()方法返回true,当这些文件没有包含在列表中时,accept()返回false.

2.流的概念:

Java程序通过流来完成输入/输出.流是生产或消费信息的,抽象.流通过Java的输入输出系统与实际的物理设备链接.尽管与他们链接的物理设备不尽相同,所有流的行为具有同样的方式.这样,相同的输入/输出类和方法适用于所有类型的外部设备.Java中流的实现是在java.io包定义的类层次结构内部.

输入/输出流:输入/输出时,数据在通信通道中流动,所谓"数据流(stream)"指的是所有数据通信通道之中,数据的起点和终点.信息的通信就是一个数据流.只要是数据从一个地方"流"到另外一个地方,这种数据流动的通道都可以称为数据流.

若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个"输出数据流"(数据从程序流出"),若程序是数据流的终点,这个数据流对程序而言就是一个"输入数据流"(数据从程序外流向程序).

3.java.io中的类可以如下分类:
①从功能分:输入流和输出流.

②从流的结构上:字节流(以字节为单位或称面向字节)和字符流(以字符为处理单位或称面向字符)

字节流的基础是InputStream和OutputStream这两个抽象类.

字符流输入输出的基础是抽象类Reader和Writer.

③节点流和过滤流:从特定的地方读写的流类,例如:磁盘或一块内存区域.

过滤流:使用节点流作为输入或输出.过滤流是使用一个已经存在的输入流或输出流连接创建的.

4.在最底层,所有的输入/输出都是字节形式的,基于字符的流只是为处理字符提供方便有效的方法.

5.读取数据的逻辑为:

open a stream

while more information

read information

close the stream

写数据的逻辑为:

open a stream

while more information

write information

close the stream

6.InputStream的其他方法:

long skip(long n):在输入流中跳过n个字节,并返回实际跳过的字节数.

int available():返回在不发生阻塞的情况下,可读取的字节数.

void close():关闭输入流,释放和这个流相关的系统资源.

void mark(int readlimit):在输入流的当前位置放置一个标记,如果读取的字节数多余readlimit设置的值,则流忽略这个标记.

void reset():返回到上一个标记.

boolean markSupported():测试当前流是否支持mark和reset方法,如果支持,返回true,否则返回false.

7.Outputstream:

三个基本的写方法:

abstract void write(int b)

void write(byte[] b)

void write(byte[] b,int off,int len):网输出流中写入数组b中从偏移量off开始的len个字节的数据.

void flush():刷新输出流,强制缓冲区中的输出字节被写出.

void close():关闭输出流,释放和这个流相关的系统资源.

8.OutputStream中包含一套字节输出流需要的方法,可以完成最基本的输出数据到输出流的功能.当Java程序要将数据输出到外设时,可根据数据的不同形式,创建一个适当的OutputStream子类型的对象来完成于该外设的链接.然后再调用执行这个刘类对象的特定输出方法来实现对相应外设的输出操作.

9.在InputStream类和OutputStream类子类中,FilterInputStream和FilterOutputStream过滤流抽象类又派生出DataInputStream和DataOutPutStream数据输入输出类等子类.

10.过滤流的主要特点是:在输入和输出数据的同时能对所传输的数据做指定类型或格式的转换,即可实现对二进制字节数据的理解和编码转换.

11.数据输入流DataInputStream中定义了多个针对不同类型数据的读方法.如readByte().readBoolean(),readShort(),readChar(),readInt(),readLong(),readFloat(),readLine()等.

12.数据输出流中DataOutPutStream中定义了多个针对不同类型数据的写方法,如writeByte(),writeBoolean(),writeShort(),writeChar(),writeInt(),writeLong(),writeFloat(),writeDouble(),writeChars()等.

13.过滤流在读/写数据的同时可以对数据经行处理,它提供了同步机制,是的某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行操作所带来的意想不到的结果.

14.FilterInputStream和FilterOutputStream分别是作为所有过滤输入流和输出流的父类.

15.FileInputStream 和FileOutputStream节点流,用于从文件中读取或往文件中写入数据,如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件.

BufferedInputStream和BufferedOutputSteam过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率.

DataInputStream和DataOutputStream过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能.

PipeInputSteam和PipedOutputSteam:管道流,用于线程间的通信局.一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入,要使管道流有用,必须同时构造管道流输入流和管道流输出流.

16.Java的I/O库提供了一个称作链接的机制,可以将一个流与另一个流首尾相接,形成一个流管道的链接,这种机制实际上是一种被称为Decorator(装饰)设计模式的应用.

17.通过流的链接,可以动态的增加流的功能,而这种功能的增加时通过组合一些流的基本功能而动态获得的,

18.为方便使用计算机常用的输入输出设备,各种高级语言与操作系统对应,都规定了可用的标准设备(文件).所谓标准设备(文件),也称为预定义设备(文件),在程序中使用这些设备(文件)时,可以不用专门的打开操作就能简单的应用,一般的,标准输入设备室键盘,标准输出设备室终端显示器,标准错误输出设备也是显示器.

19.所有的Java程序自动导入java.lang包,该包定义个名为System的类,该类封装了运行时环境的多方面信息,例如,使用它的某些方法,你能获得当前时间和系统的不同属性.System同时包含了三个预定义的流变量,in,out和err.这些成员在System中时被定义成public和static型的,这意味着他们可以不引用特定的System对象而被用于程序的其他部分.

20.System.out是保准的输出流.默认情况下,它是一个控制台.System.in是标准的输入,默认情况下,它指的是键盘.System.err指的是标准错误流,她默认是控制台,然而,这些流可以重定向到任何兼容的输入/输出设备.

21.System.in是InputStream的对象,System.out和System.err是PrintStream的对象.它们都是字节流,尽管他们用来读写外设的字符.如果愿意,你可以用基于字符的流来包装他们.

22.System类的变量in表示标准输入流,其定义为:

publib static final InputStream in

标准输入流已打开,做好踢欧冠呢输入数据的准备.一般这个流对应键盘输入,可以使用InputStream类的read()和skip(long n)等方法来从输入流获得数据.read()从输入流中读一个字节,skip(long n)在输入流中跳过n个字节.

23.System类的类变量out表示标准输出流,其定义为:

public static final PrintStream out

标准输出流也已打开,做好结束数据地准备,一般这个流对应显示器输出.

可以使用PrintStream类的print()和println()等等方法来输出数据,这两个方法支持Java的任意基本类型作为参数.

24.System类的类变量err表示标准错误输出流,其定义为:

public static final PrintStream err

标准错误输出流已打开,做好结束数据的准备,一般这个流野可以对应显示器输出,与System.out一样,可以访问PrintStream类的方法.

25.Java提供了一系列的读写文件的类和方法,在Java中,所有的文件都是字节形式的,Java提供从文件读写字节的方法,而且,Java允许在字符形式的对象中使用字节文件流.

26.两个最常用流类是FileInputStream和FileOutputStream,它们生成与文件链接的字节流.为打开文件,你只需创建这些类中某一类的一个对象.在构造方法中以参数形式指定文件的名称.

27.当你对文件的操作结束后,需要调用close()来关闭文件.

void close() throws IOException

28.FileInputStream类创建一个能能从文件读取字节的InputStream类,它的两个常用的构造方法如下:

FileInputStream(String filepath)

FileInputStream(File fileObj)

它们都能引发FileNotFoundException异常,这里,filepath是文件的全称路径,fileObj是描述该文件的File对象.

为了读文件,可以使用在FileInputStream中定义read()方法.

int read() throws IOException

该方法每次被调用,它仅从文件中读取一个字节并将该字节以整数形式返回.当读到文件尾时,read()返回-1,该方法可以引发IOException异常.

29.FileOutputStream创建了一个可以向文件写入字节的类OutputStream,它常用的构造方法如下:

FileOutputStream(String filePath)

FileOutputStream(File fileObj)

FileOutputStream(String filePath,boolean append)

它们可以引发IOException或SecurityException异常,这里filePath是文件的全称路径,fileObj是描述该文件的File对象,如果append为true,文件以追加模式打开,即新写入的字节将附加在文件的末尾,而不是从头开始.

30.FileOutputStream的创建不依赖于文件是否存在,在创建对象时,FileOutputStream在打开输出文件之前创建它,这种情况下你视图打开一个只读文件,会引发一个IOException异常.

31.向文件中写数据,需用FileOutputStream定义的write()方法,它的最简单形式如下:

void write(int byteval) throws IOException

Writes the specified byte to this file output stream. Implements the write method of OutputStream.

byteval - the byte to be written.

32.注意:不像其他的计算机语言,包括C和C++,这些语言用错误代码报告数据错误,而Java用异常处理机制.这样不仅使文件处理更为简洁,而且使用Java正在执行输入时容易区分是文件出错还是EOF条件问题.在C/C++中,很多输入函数在出错时和到达文佳结尾时返回相同的值(也就是说,在C/C++中,EOF情况与输入错误情况映射形同).这通常意味着究竟是哪种事件发生.Java中,错误通过异常引发,而不是通过read()的返回值.这样当read()返回-1时,它仅表示一点:遇到了文件结尾.

33.ByteArrayInputStream是把字节数组当成源的输入流.该类有两个构造方法,每个构造方法需要一个字节数组提供数据源:

ByteArrayInputStream(byte array[])

ByteArrayInputStream(byte array[],int start,int numBytes)

这里,array是输入源.第二个构造方法创建了一个InputStream类,该类从字节数组的子集生成,以start指定索引的字符为起点,长度由numBytes决定.

34.ByteArrayInputStream实现mark()和reset()方法,然而,如果mark()不被调用,reset()在流的开始设置流指针-----该指针式传递给构造方法的字节数组的首地址.

35.ByteArrayOutputStream(字节数组输出流)

ByteArrayOutputStream是一个把字节数组当做输出流的实现.ByteArrayOutputStream有两个构造方法:

ByteArrayOutputStream()

ByteArrayOutputStream(int numBytes)

在第一种形式里,一个32位字节的缓冲区被生成.第二个构造方法生成一个numBytes大小的缓冲区.缓冲区保存在ByteArrayOutputStream的受保护的buf成员里.缓冲区的大小在需要的情况下会自动增加.缓冲区保存的字节数是由ByteArrayOutputStream的受保护的count域保存的.

writeTo()方法:将此字节数组输出流的全部内容写入到指定的输出流中.

reset:将此字节数组输出流的count字段重置为零,从而丢弃输出流中目前已经积累的所有输出.通过重新使用已分配的缓冲区空间,可以再次使用该输出流.

36.缓冲字节流:

对于字节流,和缓冲流(buffered stream),通过把内存缓冲区连到输入/输出流扩展一个过滤流.该缓冲区允许Java对多个字节同时进行输入/输出操作,提高了程序性能.因为缓冲区可用,所有可以跳过,标记和重新设置流.缓冲区字节流类是:

BufferedInputStream和BufferedOutputStream.

PushbackInputStream也可以实现缓冲流.

37.若处理的数据量较多,为避免每个字节的读写都对流进行,可以使用过滤流类的子类缓冲流,缓冲流建立一个内部缓冲区,输入输出数据先读写到缓冲区中进行操作,这样可以提高文件流的操作效率.

38.缓冲输入/输出时一个非常普通的性能优化,Java的BufferedInputStream类允许把任何InputStream类"包装"成缓冲流并使它的性能提高.

BufferedInputStream有两个构造方法:

BufferedInputStream(InputStream inputStream)

BufferedInputStream(InputStream inputStream,int bufSize)

第一种形式创建BufferedInputStream流对象并为以后的使用保存InputStream参数in,并创建一个内部缓冲区数组来保存输入数据.

第二种形式用指定的缓冲区大小size 创建BufferedInputStream流对象,并为以后的使用报讯InputStream参数in.

39.缓冲一个输入流同样提供了在可用缓冲区的流内支持向后移动的必备基础.出了在任何InputStream类中执行read()和skip()方法外,BufferedInputStream同样支持mark()和reset()方法.

BufferedInputStream.markSupported()返回true是这一支持的体现.

40.当创建缓冲输入流BufferedInputStream时,一个输入缓冲区数组被创建,来自流的数据填入缓冲区,一次可填入许多字节.

41.public void mark(int readlimit):再次输入流中标记当前的位置,对reset方法的后续调用会在最后标记的位置重新定位此流,以便后续读取重新读取相同的字节.readlimit表示:在标记位置变为无效之前可以读取字节的最大限制。

42.public void reset():将此流重新定位到对此输入流最后调用mark()方法时的位置.

43.缓冲输入流BufferedOutStream类提供和FileOutputStream类同样的写操作方法,但所有输出全部写入缓冲区中.当写满缓冲区或关闭输出流时,它再一次性输出到流,或者使用flush()方法主动将缓冲区输出到流.

44.BufferedOutputStream与任何一个OutputStream相同,除了用一个另外的flush()方法来保证数据缓冲区被写入到实际的输出设备.BufferedOutputStream通过减小系统写数据的时间提高性能.

45.缓冲输出的构造方法:BufferedOutputStream(OutputStream outputStream)

BufferedOutputStream(OutputStream outputStream,int bufSize)

第一种形式创建了一个使用512字节缓冲区的缓冲流.

第二种形式,缓冲区的大小由bufsize参数传入.

46.想要在程序结束之前将缓冲区里的数据写入磁盘,除了填满缓冲区或关闭输出流外,还可以显示调用flush()方法.flush()方法的声明为:

public void flush() throws IOException

47.在调用完BufferedOutputStream后一定要flush或者将其close掉,否则缓冲区中的字节不会输出来.

48.PushbackInputStream(推回输入流):

缓冲的一个新颖的用法是推回(pushback). Pushback用于输入流允许字节被读取然后返回(即"推回")到流. PushbackInputStream类实现了这个想法.它提供了一种机制来"窥视"在没有收到破换的情况下输入流生成了什么.

49.PushbackInputStream的两个构造方法:

PushbackInputStream(InputStream inputStream)

PushbackInputStream(InputStream inputStream,int numBytes)

第一种形式创建了一个允许一个字节推回到输入流的流对象.

第二种形式创建了一个具有numBytes长度缓冲区的推回缓冲流. 它允许多个字节推回到输入流.

50.除了具有InputStream形同的方法,PushbackInputStream提供了unread()方法.表示如下:

void unread(int ch)

void unread(byte b[])

void unread(byte buffer[],int offset,int numChars)

第一种形式推回ch的地位字节,它将是随后调用read()方法返回的下一个字节.

第二种形式推回buffer缓冲器中的字节.推回一个 byte 数组:将其复制到推回缓冲区之前。此方法返回后,要读取的下一个字节的值将为 b[0],该字节之后的字节的值将为 b[1],依此类推。

第三种形式推回buffer中从offset出开始的numChars个字节.推回 byte 数组的某一部分:将其复制到推回缓冲区之前。此方法返回后,要读取的下一个字节的值将为 b[off],该字节之后的字节的值将为 b[off+1],依此类推。

51.SequenceInputStream类允许链接多个InputStream流.SequenceInputStream表示其他输入流的逻辑串联.它从输入的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,一次类推,直到到达包含的最后一个输入流的文件末尾为止.

52.SequenceInputStream的构造不同于任何其他的InputStream.SequenceInputStream构造方法要么使用一对InputStream,要么用InputStream的一个Enumeration,显示如下:
SequenceInputStream(InputStream first,InputStream second)

SequenceInputStream(Enumeration streamEnum)

53.操作上来说,该类满足读取完第一个InputStream后转去读取第二个流的读取要求.使用Enumeration的情况下,它将继续读取所有InputStream流直到最后一个被读完.

54.DataInputStream与DataOutPutStream

提供了允许从流读写任意对象与基本数据类型功能的方法.

字节流FileInputStream 和 FileInputStream只能提供纯字节或字节数组的输入/输出,如果要进行基本数据类型如整数和浮点数的输入/输出,则要用到过滤流类的子类二进制数据文件流DataInputStream和DataOutputStream类,这两个类的对象必须和一个输入类或输出类联系起来,而不能直接用文件名或文件对象建立.不能以数据类型读文件.

55.流类分层:把两种类结合在一起从而构成过滤流,其方法是使用一个已经存在的流来构造另一个流.(Pattern of Decorator)

56.继承自FilerInputStream和FilterOutputStream的类,比如DataInputStream和BufferedInputStream,可以把它们结合进一个新的过滤流(也即继承自FilterOutputStream的类)中以构造你需要的流.如: DataInputStream din = new DataInputStream(new BufferedInputStream (new FileInputStream(“employee.dat”);

57.使用数据文件流的一般步骤:

  • 建立字节文件流对象
  • 基于字节文件流对象建立数据文件流对象.
  • 用流对象的方法对基本类型的数据进行输入/输出.

58.DataInputStream类的构造方法如下:

DataInputStream(InputStream in)创建过滤流FilerInputStream对象并为以后的使用保存InputStream参数in

DataOutputStream类的构造方法如下:

DataOutputStream(OutputStream out)创建输出数据流对象,写数据到指定的OutputStream

59. 管道流:

管道流,用于线程间的通信,一个线程的PipedInputStream对象从另一线程的PipedOutputStream对象读取输入.要使管道流有用,必须同时构造管道输入流和管道输出流.

PipedInputStream与PipedOutputStream总是成对出现的.

管道流继承自InputStream与OutputStream , 所以他们并不是过滤流.

PipedInputStream

传送输入流应该链接到传送输出流; 传说红输入流会提供药写入传送输出流的所有数据字节. 通常,数据由某个线程从PipedInputStream对象读取, 并由其他线程将其写入到相应的PipedOutputStream. 不建议对着两个对象尝试使用单线程,因为这样可能会死锁该线程.传送输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开.

PipedOutputStream

传送输出流可以连接到传送输入流,可以创建通信管道.传送输出流是管道的发送端. 通常, 数据由某个线程写入 PipedOutputStream 对象, 并由其他线程从连接的 PipedInputStream 读取. 不建议对这两个对象尝试使用单线程,因为这样可能会死锁该线程.

PipedInputStream 的构造方法:

PipedInputStream()

创建尚未连接的PipedInputStream

PipedInputStream(PipedOutputStream src)

创建PipedInputStream , 以使其连接到传送输出流 src .

public void connect ( PopedOutputStream src)

使此传送输入流连接到传送输出流src. 如果此对象已经连接到其他某个传送输出流,则跑出IOException.

如果src为未连接的传送输出流, snk为未连接的传送输入流, 则可以通过以下任一调用使其连接:

snk.connect(src)

src.connect(snk)

这两个调用的效果相同.

PipedOutputStream 构造方法:

PipedOutputStream()

创建尚未连接到传送输入流的传送输出流.

PipedOutputStream(PipedInputStream snk)

创建连接到指定传送输入流的传说红输出流.

public void connect(PipedInputStream snk)

将此传送输出流连接到接受者. 如果此对象已经连接到其他某个传送输入流, 则抛出IOException.

 

60.字符流:

字符流层次结构的顶层是Reader和Writer抽象类.

字符输入/输出类是在Java 1.1中新增内容.

字符流的读写等方法与字节流的相应方法都很类似, 但读写对象使用的是字符.

Reader中包含了一套字符输入流需要的方法,可以完成最基本的从输入流读入数据的功能.当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的Reader子类类型的对象来完成于该外设的连接,然后再调用执行这个流类对象对特定输入法,如read(), 来实现对相应外设的输入操作.

Writer中包含一套字符输出流需要的方法,可以完成最基本的输出数据到输出流的功能, 当Java 程序需要将数据输出到外设时, 可根据数据的不同形式, 也要穿件一个适当的Writer子类类型的对象来完成与该外设的连接, 然后再调用执行这个流类对象的特定输出方法,如write(), 来实现对相应外设的输出操作.

61.Java程序语言使用Unicode来表示字符串和字符,Unicode使用两个字节来表示一个字符, 即一个字符占16位

62. InputStreamReader和 OutputStreamWriter类

这是java.io包中用于处理字符流的基本类, 用来在字符流和字符流之间搭一座"桥". 这里字节流的编码规范与具体的平台有关, 可以在构造流对象时指定规范, 也可以使用当前平台的缺省规范.

63.InputStreamReader和OutputStringWriter类的主要构造方法如下:

public InputStreamReader(InputStream in)

public InputStreamReader(InputStream in, String enc)

public OutputStreamWriter(OutputStream out)

public OutputStreamWriter(OutputStream out, String enc)

其中in和out分别为:输入和输出字节流对象,enc为指定的编码规范(若无此参数,表示使用当前默认平台的缺省规范,可用getEncoding()方法得到当前字符流所用的编码方式).

读写字符的方法read(), write() ,关闭流的方法close()等与Reader和Writer类的同名方法用法都是类似的.

64.FileReader类创建了一个可以读取文件内容的Reader类,FileReader继承于InputStreamReader. 它最常用的构造方法如下:

FileReader(String filePath)

FileReader(File fileObj)

每一个都能一发一个FileNotFoundException异常,这里,filePath是一个文件的完整路径,fileObj是描述该文件的File对象.

65.FileWriter创建一个可以写文件的Writer类, FileWriter继承与OutputStreamWriter.它最常用的构造方法如下:

FileWriter(String filePath)

FileWriter(String filePath, boolean)

FileWriter(File fileObj)

append:如果为true,则将字节写入文件末尾处,而不是写入文件开始处.

它们都可以引发IOException或SecurityException异常,这里,filePath是文件的完全路径,fileObj是描述该文件的File对象. 如果append为true, 输出是附加到文件的末尾的.

FileWriter类的创建不依赖于文件存在与否. 在创建文件之前, FileWriter将在创建对象时打开它来作为输出. 如果你试图打开一个只读文件, 将引发一个IOException异常. 

66.CharArrrayReader是一个把字符数组作为源的输入流的实现.该类有两个构造方法,每一个构造方法都需要一个字符数组提供数据源.

CharArrayReader(char arrray[])]

CharArrayReader(char array[], int start, int numChars)

这里,array是输入源,第二个构造方法从你的字符数组的子集创建了一个Reader,该子集的start指定的索引开始,长度为numChars.

67.CharArrayWriter实现了以数组作为目标的输出流. CharArrayWriter有两个构造方法;

CharArrayWriter()

CharArrayWriter(int numChars)

第一种形式,创建了一个默认长度的缓冲区.

第二种形式,缓冲区长度由numChars指定. 缓冲区保存在CharArrayWriter的buf成员中. 缓冲区大小在需要的情况下可以自动增长. 缓冲区保持的字符数包含在CharArrayWriter的count成员中. buf和count都是受保护的域(protected)

68.BufferedReader: BufferedReader 通过缓冲输入提高性能. 它有两个构造方法

BufferedReader(Reader inputStream)

BufferedReader(Reader inputStream, int bufSize)

第一种形式创建了一个默认缓冲区长度的缓冲字符流.

第二种形式, 缓冲区长度由bufSize传入.

和字节流的情况相同, 缓冲一个输入字符流同样提供支持可用缓冲区中流内反向移动的基础. 为支持这点, BufferedReader 实现了 mark() 和 reset()方法, 并且 BufferedReader.markSupported() 返回true.

BufferedWriter是一个增加了flush()方法的Writer. flush()方法可以用来确保数据缓冲区确实被写到实际的输出流. 用BufferedWriter可以通过减小数据被实际写到输出流的次数而提高程序的性能.

BufferedWriter(Writer outputStream)

BufferedWriter(Writer outputStream, int bufSize)

第一种形式创建了使用默认大小缓冲区的缓冲流, 第二种形式中, 缓冲区的大小是由bufSize参数传入的.

69.PushbackReader类允许一个或多个字符被传送回输入流. 这使你可以对输入流进行预测. 下面是它的两个构造方法:

PushbackReader(Reader inputStream)

PushbackReader(Reader inputStream, int bufSize)

第一种形式创建了一个允许单个字节被退回的缓冲流.

第二种形式, 退回缓冲区的大小由bufSize参数传入.

PushbackReader提供了unread()方法. 该方法 返回一个或多个字符到调用的输入流. 它有下面的三种形式:

void unread(int ch)

void unread(char buffer[])

void unread(char buffer[], int offset, int numChars)

第一种形式退回ch传入的字符. 它是被并发调用的read()返回的下一个字符. 第二种形式返回buffer中的字符. 第三种形式推回buffer中从offset开始的numChars个字符.

70.字符集编码:

ASCII(American Standard Code for Information Interchange, 美国标准信息交换码), 每一个ASCII码与一个8位(bit)二进制数对应. 其最高位是0, 相应的十进制数是0~127. 如, 数字"0" 的编码用十进制数表示就是48. 另外128个扩展的ASCII码, 最高位都是1, 由一些制表符和其他字符组成, ASCII是现今最通用的单字节编码系统.

GB2312:GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集—基本集》。主要用于给每一个中文字符指定相应的数字,也就是进行编码。一个中文字符用两个字节的数字来表示,为了和ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。

GBK:为了对更多字符进行编码,国家又发布了新的编码系统GBK(GBK的K是"扩展"的汉语拼音首字母),新的编码系统中完全兼容GB2312,还对繁体中文、一些不常用的汉字和许多符号进行了编码。

ISO-8859-1:是西方国家所使用的字符编码集,是一种单字节的字符集,而英文实际上只用了其中数字小于128的部分。

Unicode:这是一种通用的字符集,队友所有语言的文字进行了统一编码, 对于每一个字符都用2个字节来表示, 对于英文字符采取前加"0"字节的策略实现等长兼容. 如"a"的ASCII码为0x61, Unicode就为0x00,0x61.(在internet上传输效率较低)

UTF-8:Eight-bit UCS Transformation Format, (UCS, Universal Character Set,通用字符集,UCS是所有其他字符集标注你的一个超集). 一个7位的ASCII码值, 对应的UTF码是一个字节. 如果字符时0x0000,或在0x0080与0x0800与0xffff之间, 对应的UTF码是三个字节(汉字为3个字节)

71.RandomAccessFile包装了一个随机访问的文件. 它不是派生于InputStream和OutputStream, 而是实现定义了基本输入/输出方法的DataInput和DataOutput接口, 它支持定位请求--也就是说,可以在文件内部放置文件指针, 它有两个构造方法.

RandomAccessFile(File fileObj,String access) throws FileNotFoundException

RandomAccessFile(String filename,String access) throws

FileNotFoundException

第一种形式,fileObj制定了作为File对象打开的文件的名称.

第二种形式,文件名是由filename参数传入的.

两种情况下,access都决定允许访问何种文件类型,如果是"r",那么文件可读不可写,如果是"rw",文件以读写模式打开.

RandomAccessFile类同时实现了DataInput和DataOutput接口,提供了对文件随机存取的功能,利用这个类可以在文件的任位置读取或写入数据.

RandomAccessFile类提供了一个文件指针,用来标志要进行读写操作的下一个数据的位置.

public long getFilePointer()

返回到此文件开头的偏移量(以字节为单位), 在该位置发生下一个读取或写入操作.

public void seek(long pos)

设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。偏移量的设置可能会超出文件末尾。偏移量的设置超出文件末尾不会改变文件的长度。只有在偏移量的设置超出文件末尾的情况下对文件进行写入才会更改其长度。

72. 常用方法:

public long length()

返回此文件的长度.

public long skipBytes(int n)

尝试跳过输入的 n 个字节以丢弃跳过的字节。

此方法可能跳过一些较少数量的字节(可能包括零)。这可能由任意数量的条件引起;在跳过 n 个字节之前已到达文件的末尾只是其中的一种可能。此方法从不抛出 EOFException。返回跳过的实际字节数。如果 n 为负数,则不跳过任何字节。

73.序列化:

将对象转换为字节流保存起来, 并在以后还原这个对象, 这种机制叫做对象序列化.

将一个对象保存到永久存储设备上称为持久化.

一个对象要想能够实现序列化,补习实现Serializable接口或Externalizable接口.

74.序列化: 是把一个对象的状态写入一个字节流的过程. 当你想要把你的程序状态存到一个固定的存储区域例如文件时,它是很管用的

假设一个被序列化的对象引用了其他对象, 同样,其他对象又引用了更多对象. 这一系列的对象和它们的关系形成了一个顺序图标. 在这个对象图标中也有循环引用. 也就是说, 对象x可以包含一个对象Y的引用,对象Y同样可以包含一个对象X的引用. 对象同样可以包含它们自己的引用,对象序列化和反序列化被设计出来并在这一假定条件下运行良好. 如果你试图序列化一个对象图表中的顶层的对象,所有的其他的引用对象都被循环的定位和序列化. 同样,在反序列化过程中,所有的这些对象以及它们的引用都被正确的恢复.

75.

当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化

76.Serializable接口:

只有一个实现Serializable接口的对象可以被序列化工具存储和恢复. Serializable接口没有定义任何成员, 它们只用来表示一个类可以被序列化, 如果一个类可以序列化,它的所有子类都可以序列化.

声明成transient的变量不被序列化工具存储.同样,static变量也不被存储.

77.Externalizable接口:

Java的序列化和反序列化的工具被设计出来,所以很多存储和恢复对象的工作自动进行. 然而,在某些情况下,程序员必须控制这些过程, 例如: 在需要使用压缩或加密的技术时,Externalizable接口为这些情况而设计.

Externalizable接口定义了两个方法:

void readExternal(ObjectInput inStream)

throws IOException,ClassNotFoundException

void writeExternal(ObjectOutput outStream)

throws IOException

这些方法中,inSteam是对象被读取的字节流,outStream是对象被写入的字节流.

Externalizable实例类的唯一特性是可以被写入序列流中,该类负责保存和恢复实例内容. 若某类要完全控制某一对象及其超类型的流类格式和内容,则他要实现Externalizable接口的writerExternal和readExternal方法. 这些犯法必须显式与超类型进行协调以保存其状态. 这些方法代替自定义的writeObject和readObject方法实现.

78.ObjectOutput接口:

ObjectOutput继承DataOutput接口并且支持对象序列化, 特别注意writeObject()方法,它被称为序列化一个对象. 所有这些方法在出错情况下引发IOException异常.

79.ObjectOutputStream类

ObjectOutputStream类继承OutputStream 类和实现ObjectOutput接口. 它负责向流写入对象, 该类的构造方法如下:
ObjectOutputStream(OutputStream outStream) throws IOException

参数outStream是序列胡的对象将要写入的输出流.

ObjectInput

ObjectInput接口继承DataInput接口, 它支持对象序列化. 特别注意readObject()方法, 它叫反序列化对象. 所有这些方法在出错情况下引发IOExcepion异常.

ObjectInputStream 继承InputStream类并实现ObjectInput接口.

ObjectInputStream负责从流中读取对象. 该类的构造方法如下:

ObjectInputStream(InputStream inStream)

throws IOException,StreamCorruptedException

参数inStream是序列化对象将被读取的输入流.

序列化:

在序列化和反序列化进程中需要特殊处理的Serializable类应该实现以下方法:

private void writeObject(java.io.ObjectOutputStream stream)

throws IOException

private void readObject(java.io.ObjectInputStream Stream)

throws IOException,ClassNotFoundExcetpion

这两个方法不属于任何一个类和任何一个接口,是非常特殊的方法.

总结:InputStream和OutputStream:字节流的输入输出.

Reader和Writer:字符流的输入输出.

流的链接:(Java I/O库的设计原则)

posted @ 2011-03-19 19:04  donaldjohn  阅读(242)  评论(0编辑  收藏  举报