当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>Java入门

Java编程那些事儿85——IO类体系

    Java编程那些事儿系列文章(全集目录)

    11.2 I/O类体系

    在JDK API中,基础的IO类都位于java.io包,而新实现的IO类则位于一系列以java.nio开头的包名中,这里首先介绍java.io包中类的体系结构。

    按照前面的说明,流是有方向的,则整个流的结构按照流的方向可以划分为两类:

    1、输入流:

    该类流将外部数据源的数据转换为流,程序通过读取该类流中的数据,完成对于外部数据源中数据的读入。

    2、输出流:

    该类流完成将流中的数据转换到对应的数据源中,程序通过向该类流中写入数据,完成将数据写入到对应的外部数据源中。

    而在实际实现时,由于JDK API历史的原因,在java.io包中又实现了两类流:字节流(byte stream)和字符流(char stream)。这两种流实现的是流中数据序列的单位,在字节流中,数据序列以byte为单位,也就是流中的数据按照一个byte一个byte的顺序实现成流,对于该类流操作的基本单位是一个byte,而对于字节流,数据序列以char为单位,也就是流中的数据按照一个char一个插入的顺序实现成流,对于该类流操作的基本单位是一个char.

    另外字节流是从JDK1.0开始加入到API中的,而字符流则是从JDK1.1开始才加入到API中的,对于现在使用的JDK版本来说,这两类流都包含在API的内部。在实际使用时,字符流的效率要比字节流高一些。

    在实际使用时,字符流中的类基本上和字节流中的类对应,所以在开始学习IO类时,可以从最基础的字节流开始学习。

    在SUN设计JDK的IO类时,按照以上的分类,为每个系列的类设计了一个父类,而实现具体操作的类都作为该系列类的子类,则IO类设计时的四个体系中每个体系中对应的父类分别是:

    11.2.1 字节输入流InputStream

    该类是IO编程中所有字节输入流的父类,熟悉该类的使用将对使用字节输入流产生很大的帮助,下面做一下详细的介绍。

    按照前面介绍的流的概念,字节输入流完成的是按照字节形式构造读取数据的输入流的结构,每个该类的对象就是一个实际的输入流,在构造时由API完成将外部数据源转换为流对象的操作,这种转换对程序员来说是透明的。在程序使用时,程序员只需要读取该流对象,就可以完成对于外部数据的读取了。

    InputStream是所有字节输入流的父类,所以在InputStream类中包含的每个方法都会被所有字节输入流类继承,通过将读取以及操作数据的基本方法都声明在InputStream类内部,使每个子类根据需要覆盖对应的方法,这样的设计可以保证每个字节输入流子类在进行实际使用时,开放给程序员使用的功能方法是一致的。这样将简化IO类学习的难度,方便程序员进行实际的编程。

    默认情况下,对于输入流内部数据的读取都是单向的,也就是只能从输入流从前向后读,已经读取的数据将从输入流内部删除掉。如果需要重复读取流中同一段内容,则需要使用流类中的mark方法进行标记,然后才能重复读取。这种设计在使用流类时,需要深刻进行体会。

    在InputStream类中,常见的方法有:

    a、available方法

    public int available() throws IOException

    该方法的作用是返回当前流对象中还没有被读取的字节数量。也就是获得流中数据的长度。

    假设初始情况下流内部包含100个字节的数据,程序调用对应的方法读取了一个字节,则当前流中剩余的字节数量将变成99个。

    另外,该方法不是在所有字节输入流内部都得到正确的实现,所以使用该方法获得流中数据的个数是不可靠的。

    b、close方法

    public void close() throws IOException

    该方法的作用是关闭当前流对象,并释放该流对象占用的资源。

    在IO操作结束以后,关闭流是进行IO操作时都需要实现的功能,这样既可以保证数据源的安全,也可以减少内存的占用。

    c、markSupported方法

    public boolean markSupported()

    该方法的作用是判断流是否支持标记(mark)。标记类似于读书时的书签,可以很方便的回到原来读过的位置继续向下读取。

    d、reset方法

    public void reset() throws IOException

    该方法的作用是使流读取的位置回到设定标记的位置。可以从该位置开始继续向后读取。

    e、mark方法

    public void mark(int readlimit)

    为流中当前的位置设置标志,使得以后可以从该位置继续读取。变量readlimit指设置该标志以后可以读取的流中最大数据的个数。当设置标志以后,读取的字节数量超过该限制,则标志会失效。

    f、read方法

    read方法是输入流类使用时最核心的方法,能够熟练使用该方法就代表IO基本使用已经入门。所以在学习以及后期的使用中都需要深刻理解该方法的使用。

    在实际读取流中的数据时,只能按照流中的数据存储顺序依次进行读取,在使用字节输入流时,读取数据的最小单位是字节(byte)。

    另外,需要注意的是,read方法是阻塞方法,也就是如果流对象中无数据可以读取时,则read方法会阻止程序继续向下运行,一直到有数据可以读取为止。

    read方法总计有三个,依次是:

    public abstract int read() throws IOException

    该方法的作用是读取当前流对象中的第一个字节。当该字节被读取出来以后,则该字节将被从流对象中删除,原来流对象中的第二个字节将变成流中的第一个字节,而使用流对象的available方法获得的数值也将减少1.如果需要读取流中的所以数据,只要使用一个循环依次读取每个数据即可。当读取到流的末尾时,该方法返回-1.该返回值的int中只有最后一个字节是流中的有效数据,所以在获得流中的数值时需要进行强制转换。返回值作成int的目的主要是处理好-1的问题。

    由于该方法是抽象的,所以会在子类中被覆盖,从而实现最基础的读数据的功能。

    public int read(byte[] b) throws IOException

    该方法的作用是读取当前流对象中的数据,并将读取到的数据依次存储到数组b(b需要提前初始化完成)中,也就是把当前流中的第一个字节的数据存储到b[0],第二个字节的数据存储到b[1],依次类推。流中已经读取过的数据也会被删除,后续的数据会变成流中的第一个字节。而实际读取的字节数量则作为方法的返回值返回。

    public int read(byte[] b, int off, int len) throws IOException

    该方法的作用和上面的方法类似,也是将读取的数据存储到b中,只是将流中的第一个数据存储到b中下标为off的位置,最多读取len个数据,而实际读取的字节数量则作为方法的返回值返回。

    g、skip方法

    public long skip(long n) throws IOException

    该方法的作用是跳过当前流对象中的n个字节,而实际跳过的字节数量则以返回值的方式返回。

    跳过n个字节以后,如果需要读取则是从新的位置开始读取了。使用该方法可以跳过流中指定的字节数,而不用依次进行读取了。

    从流中读取出数据以后,获得的是一个byte数组,还需要根据以前的数据格式,实现对于该byte数组的解析。

    由于InputStream类是字节输入流的父类,所以该体系中的每个子类都包含以上的方法,这些方法是实现IO流数据读取的基础。

共3页 首页 上一页 1 2 3 下一页 尾页 跳转到
相关内容
赞助商链接