黑马程序员技术交流社区

标题: Java IO 流 一些散乱的笔记 [打印本页]

作者: leixing1012    时间: 2015-9-19 20:21
标题: Java IO 流 一些散乱的笔记
  Java IO流从流结构上可分为字节流(Byte Streams,以字节为处理单位或称面向字节)和字符流(Character Streams,以字符为处理单位或称面向字符)。

  字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。

  字符流是Java 1.1版后新增加的以字符为单位进行输入输出处理的流,字符流输入输出的基础是抽象类Reader和Writer。



  另一种分类将流分为节点流和过滤流。

  字节流和字符流都是符合装饰者设计模式的,所以字节流和字符流都有自己的节点流和过滤流。它们的使用方式都是类似的。


字节流的过滤流

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

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

  数据输入流DataInputStream中定义了多个针对不同类型数据的读方法;数据输出流DataOutputStream中定义了多个针对不同类型数据的写方法。

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

  1.建立字节文件流对象;

  2.基于字节文件流对象建立数据文件流对象;

  3.用流对象的方法对基本类型的数据进行输入/输出。

  BufferedOutputStream

  缓冲流,先把内容写到内存的一块缓冲区里面,从缓冲区再往外写。

  ByteArrayInputStream是把字节数组当成源的输入流。

建立自己的输入流

  例子程序:  

import java.io.IOException;
import java.io.InputStream;

public class MyOwnStream extends InputStream
{

    protected byte[] data;

    protected int ptr;

    protected int mark = 0;

    public MyOwnStream(byte[] b)
    {
        this.data = b;
    }

    @Override
    public int read()
    {
        return (ptr < data.length) ? data[ptr++] : -1;
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException
    {
        if (this.ptr >= data.length || len < 0) { return -1; }

        if (this.ptr + len < data.length)
        {
            len = data.length - this.ptr;
        }

        if (0 == len) { return 0; }

        System.arraycopy(data, ptr, b, off, len);

        ptr += len;

        return len;
    }

    @Override
    public int available() throws IOException
    {
        // 还有多少字节没有读
        return data.length - ptr;
    }

    @Override
    public void close() throws IOException
    {
        // close和硬件相关
        // 此处仅设置成不能再读
        ptr = data.length;
    }

    @Override
    public synchronized void mark(int readlimit)
    {
        this.mark = readlimit;
    }

    @Override
    public synchronized void reset() throws IOException
    {
        if (mark < 0 || mark >= data.length) { throw new IOException(
                "The position is not valid!"); }

        ptr = mark;

    }

    @Override
    public boolean markSupported()
    {
        // 是否支持标记
        return true;
    }
}


字符流

  尽管字节流提供了处理任何类型输入/输出操作的足够的功能,它们不能直接操作Unicode字符。既然Java的一个主要目的是支持“只写一次,到处运行”的哲学,包括直接的字符输入/输出支持是必要的。

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

  Reader和Writer类也有较多的子类,与字节流类似,它们用来创建具体的字符流对象进行I/O操作。字符流的读写等方法与字节流的相应方法都很类似,但读写对象使用的是字符。

  支持装饰者模式。

  Java使用Unicode来表示字符串和字符,Unicode使用两个字节来表示一个字符,即一个字符占16位。

  InputStreamReader和OutputStreamWriter类

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

  FileReader类创建了一个可以读取文件内容的Reader类。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2