Java IO - Basic

原创 2016年08月31日 11:36:14

Java IO -Basic

目录


InputStream, OutputStream, Reader, InputStreamReader, Writer 和
OutputStreamWriter。


InputStream

package java.io;

/**
 * 所有字节输入流的超类
 */
public abstract class InputStream implements Closeable {

    // skip 的最大 buffer 大小
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;

    /**
     * 读取下一个字节,不存在就返回 -1
     */
    public abstract int read() throws IOException;

    /**
     * 从输入流中读取数据存放到 b 中
     */
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    /**
     * 最多读取 len 长度的字节数据,存放到 b 中

     */
    public int read(byte b[], int off, int len) throws IOException {
        if (b == null) { // b 是空,或者 长度信息不合法,抛出异常
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        int c = read(); // 先读取一个字节,不存在就直接返回了
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;

        int i = 1; // 上面已经读取一个了,所以从 1 开始
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }

    /**
     * 跳过 n 个字节长度的数据
     */
    public long skip(long n) throws IOException {

        long remaining = n;
        int nr;

        if (n <= 0) {
            return 0;
        }

        int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
        byte[] skipBuffer = new byte[size];
        while (remaining > 0) { 
            // 一次最多 skip MAX_SKIP_BUFFER_SIZE 字节的数据
            nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
            if (nr < 0) {
                break;
            }
            remaining -= nr;
        }

        return n - remaining;
    }

    /**
     * 返回此输入流中大概的可读字节数
     */
    public int available() throws IOException {
        return 0;
    }

    public void close() throws IOException {}

    /**
     * mark,打标记,与 reset 配合使用,
     */
    public synchronized void mark(int readlimit) {}

    /**
     * 把输入流 reset 到 mark 标记的位置
     */
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

    /**
     * 测试是否支持 mark
     */
    public boolean markSupported() {
        return false;
    }
}

OutputStream

package java.io;

/**
 * 所有字节输出流的超类
 */
public abstract class OutputStream implements Closeable, Flushable {
    /**
     * 把指定的字节 写入到输出流中,只会写 低 8 位,高 24 位忽略
     */
    public abstract void write(int b) throws IOException;

    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    public void write(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return;
        }
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);
        }
    }

    public void flush() throws IOException {
    }

    public void close() throws IOException {
    }

}

Reader

package java.io;


/**
 * 用来读取字符流的抽象类
 */

public abstract class Reader implements Readable, Closeable {

    /**
     * 流上用来进行同步操作的同步锁,对于子类来说,最好也是使用这个对象来作为锁对象
     */
    protected Object lock;

    protected Reader() {
        this.lock = this;
    }

    protected Reader(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }

    /**
     * 从输入流中读取数据到 target
     */
    public int read(java.nio.CharBuffer target) throws IOException {
        int len = target.remaining();
        char[] cbuf = new char[len];
        int n = read(cbuf, 0, len);
        if (n > 0)
            target.put(cbuf, 0, n);
        return n;
    }

    /**
     * 读取单个字符,阻塞方法
     */
    public int read() throws IOException {
        char cb[] = new char[1];
        if (read(cb, 0, 1) == -1)
            return -1;
        else
            return cb[0];
    }

    public int read(char cbuf[]) throws IOException {
        return read(cbuf, 0, cbuf.length);
    }


    abstract public int read(char cbuf[], int off, int len) throws IOException;

    /** Maximum skip-buffer size */
    private static final int maxSkipBufferSize = 8192;

    /** Skip buffer, null until allocated */
    private char skipBuffer[] = null;

    /**
     * 跳过 n 个字符
     */
    public long skip(long n) throws IOException {
        if (n < 0L)
            throw new IllegalArgumentException("skip value is negative");
        int nn = (int) Math.min(n, maxSkipBufferSize);
        synchronized (lock) {
            if ((skipBuffer == null) || (skipBuffer.length < nn))
                skipBuffer = new char[nn];
            long r = n;
            while (r > 0) {
                int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
                if (nc == -1)
                    break;
                r -= nc;
            }
            return n - r;
        }
    }

    /**
     * 告知这个流是否准备好数据了
     */
    public boolean ready() throws IOException {
        return false;
    }

    public boolean markSupported() {
        return false;
    }

    public void mark(int readAheadLimit) throws IOException {
        throw new IOException("mark() not supported");
    }

    public void reset() throws IOException {
        throw new IOException("reset() not supported");
    }

    abstract public void close() throws IOException;

}

InputStreamReader

package java.io;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.StreamDecoder;


/**
 * InputStreamReader 是字节流和字符流之间的桥梁。
 * 它读取字节然后使用特定的解码器把字节解码成字符。
 * 为了效率考虑,一般都把 InputStreamReader 包装在一个
 * BufferedReader 中
 * BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
 */

public class InputStreamReader extends Reader {

    private final StreamDecoder sd;

    /**
     * 使用默认的字符集来创建 InputStreamReader
     */
    public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }

    /**
     * 使用指定名称的字符集来创建 InputStreamReader
     */
    public InputStreamReader(InputStream in, String charsetName)
        throws UnsupportedEncodingException
    {
        super(in);
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }

    /**
     * 使用给定的字符集来创建 InputStreamReader
     */
    public InputStreamReader(InputStream in, Charset cs) {
        super(in);
        if (cs == null)
            throw new NullPointerException("charset");
        sd = StreamDecoder.forInputStreamReader(in, this, cs);
    }

    /**
     * 使用给定的字符集解码器来创建 InputStreamReader
     */
    public InputStreamReader(InputStream in, CharsetDecoder dec) {
        super(in);
        if (dec == null)
            throw new NullPointerException("charset decoder");
        sd = StreamDecoder.forInputStreamReader(in, this, dec);
    }

    /**
     * 返回字符编码的名称
     */
    public String getEncoding() {
        return sd.getEncoding();
    }

    /**
     * 读取单个字符
     */
    public int read() throws IOException {
        return sd.read();
    }

    /**
     * 读取字符到数组中
     */
    public int read(char cbuf[], int offset, int length) throws IOException {
        return sd.read(cbuf, offset, length);
    }

    /**
     * 告知是否 流 已准备好可读。当输入流魂村不空的时候,就可读了。
     */
    public boolean ready() throws IOException {
        return sd.ready();
    }

    public void close() throws IOException {
        sd.close();
    }
}

Writer

package java.io;


/**
 * 抽象类,把数据写入字符流
 */

public abstract class Writer implements Appendable, Closeable, Flushable {

    /**
     * 缓存,暂存要写入的字符串和单个字符
     */
    private char[] writeBuffer;

    /**
     * writeBuffer 的长度
     */
    private static final int WRITE_BUFFER_SIZE = 1024;

    /**
     * 流上用来进行同步操作的锁对象,子类也应该使用这个 lock 作为锁对象。
     */
    protected Object lock;

    /**
     * 锁对象是自己
     */
    protected Writer() {
        this.lock = this;
    }

    protected Writer(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }

    /**
     * 写入单个字符到 writeBuffer,只写 低 16 字节,高 16 字节忽略
     */
    public void write(int c) throws IOException {
        synchronized (lock) {
            if (writeBuffer == null){
                writeBuffer = new char[WRITE_BUFFER_SIZE];
            }
            writeBuffer[0] = (char) c;
            write(writeBuffer, 0, 1);
        }
    }

    public void write(char cbuf[]) throws IOException {
        write(cbuf, 0, cbuf.length);
    }

    abstract public void write(char cbuf[], int off, int len) throws IOException;

    public void write(String str) throws IOException {
        write(str, 0, str.length());
    }

    public void write(String str, int off, int len) throws IOException {
        synchronized (lock) {
            char cbuf[];
            if (len <= WRITE_BUFFER_SIZE) {
                if (writeBuffer == null) {
                    writeBuffer = new char[WRITE_BUFFER_SIZE];
                }
                cbuf = writeBuffer;
            } else {    // Don't permanently allocate very large buffers.
                cbuf = new char[len];
            }
            str.getChars(off, (off + len), cbuf, 0);
            write(cbuf, 0, len);
        }
    }

    public Writer append(CharSequence csq) throws IOException {
        if (csq == null)
            write("null");
        else
            write(csq.toString());
        return this;
    }

    public Writer append(CharSequence csq, int start, int end) throws IOException {
        CharSequence cs = (csq == null ? "null" : csq);
        write(cs.subSequence(start, end).toString());
        return this;
    }

    public Writer append(char c) throws IOException {
        write(c);
        return this;
    }

    abstract public void flush() throws IOException;

    abstract public void close() throws IOException;

}

OutputStreamWriter

package java.io;

import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import sun.nio.cs.StreamEncoder;


/**
 * OutputStreamWriter 是字符流和字节流之间的桥梁。
 * 字符通过特定的编码转换成字节写入到  OutputStreamWriter 中
 * 为了效率考虑,一般都会将 OutputStreamWriter 包装在一个 BufferedWriter 中。
 * Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
 */

public class OutputStreamWriter extends Writer {

    private final StreamEncoder se;

    /**
     * 使用字符集的名称来创建一个 OutputStreamWriter
     */
    public OutputStreamWriter(OutputStream out, String charsetName)
        throws UnsupportedEncodingException
    {
        super(out);
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
    }

    /**
     * 使用默认的字符集来创建一个 OutputStreamWriter
     */
    public OutputStreamWriter(OutputStream out) {
        super(out);
        try {
            se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }
    }

    /**
     * 使用给定的字符集来创建一个 OutputStreamWriter
     */
    public OutputStreamWriter(OutputStream out, Charset cs) {
        super(out);
        if (cs == null)
            throw new NullPointerException("charset");
        se = StreamEncoder.forOutputStreamWriter(out, this, cs);
    }

    /**
     * 使用特定的编码器来创建一个 OutputStreamWriter
     */
    public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
        super(out);
        if (enc == null)
            throw new NullPointerException("charset encoder");
        se = StreamEncoder.forOutputStreamWriter(out, this, enc);
    }

    /**
     * 返回编码器的名字
     */
    public String getEncoding() {
        return se.getEncoding();
    }

    /**
     * 刷新 buffer 到字节流中,而不是刷新字节流本身
     * buffer -> 字节流 -> 目标
     */
    void flushBuffer() throws IOException {
        se.flushBuffer();
    }

    /**
     * 写入单个字符
     */
    public void write(int c) throws IOException {
        se.write(c);
    }

    public void write(char cbuf[], int off, int len) throws IOException {
        se.write(cbuf, off, len);
    }

    public void write(String str, int off, int len) throws IOException {
        se.write(str, off, len);
    }

    public void flush() throws IOException {
        se.flush();
    }

    public void close() throws IOException {
        se.close();
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java IO Basic

字节流 字符流

Java Basic4(Exception and Java IO)

一、Exception Error:不可恢复,JVM一些错误 Exception:运行时与非运行时异常,可被捕获,代码本身错误。 不需要程序强制try/catch的都是运行时exception,...

【★更新★】Portal-Basic Java Web 开发框架 v3.1.1 正式发布(源码、示例及文档)

Portal-Basic Java Web应用开发框架(简称 Portal-Basic)是一套功能完备的高性能Full-Stack Web应用开发框架,内置稳定高效的MVC基础架构和DAO框架(已内置...
  • DuMiYue
  • DuMiYue
  • 2013年04月24日 10:57
  • 1136

Visual Basic 2005文件IO与数据存取秘诀

  • 2012年07月28日 17:12
  • 11.06MB
  • 下载

Portal-Basic Java Web 应用开发框架:应用篇(十) —— 新 DAO 访问接口

Portal-Basic Web应用开发框架(简称 Portal-Basic或PB)是一套功能完备的超轻量级Web应用开发框架,内置MVC Web基础架构,支持可扩展的数据访问接口(已内置Hibe...
  • DuMiYue
  • DuMiYue
  • 2012年11月16日 11:05
  • 480

Java Web开发Basic(一) tomcat和web项目了解

Java Web开发Basic(一) tomcat和web项目了解 Tomcat Tomcat目录和Web应用目录 Tomcat的目录结构 /bin 存放启动关闭脚本程序等 /con...

HTTP基本认证(Basic Authentication)的JAVA示例

HTTP基本认证工作原理以及用JAVA如何实现
  • kkdelta
  • kkdelta
  • 2014年06月04日 14:22
  • 37461
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java IO - Basic
举报原因:
原因补充:

(最多只允许输入30个字)