InputStream和OutputStream详解

书欣 Java教程 发布时间:2023-01-12 20:16:58 阅读数:14353 1
下文笔者讲述Java中InputStream和OutputStream详解,如下所示

InputStream和OutputStream简介

InputStream和OutputStream
 是io包中面向字节操作的顶级抽象类

InputStream和OutputStream的功能:
  她们是Java中输入流和输出流

InputStream输入流类中常用方法

public int read():
  从输入流中的当前位置读入一个字节(8b)的二进制数据
 然后以此数据为低位字节
 配上8个全0的高位字节合成一个16位的整型量(0~255)返回给调用此方法的语句
 若输入流中的当前位置没有数据,则返回。
public int read(byte[ ] b):
  从输入流中的当前位置连续读入多个字节保存在数组b中
  同时返回所读到的字节数
public int read(byte[]b,int off, int len):
  从输入流中的当前位置连续读入len个字节
  从数组b的第off+1个元素位置处开始存放,同时返回所读到的字节数
public int available():
  返回输入流中可以读取的字节数 
public long skip(long n):
  使位置指针从当前位置向后跳过n个字节
public void mark(int readlimit):
   在当前位置处做一个标记,并且在输入流中读取readlimit个字节数后该标记失效
public void reset():
   将位置指针返回到标记的位置
public void close():
   关闭输入流与外设的连接并释放所占用的系统资源

OutputStream流中常见方法说明

public void write(int b):
   参数b的低位字节写入到输出流
public void write(byte[ ]b):
   将字节数组b中的全部字节按顺序写入到输出流
public void write(byte[]b,int off,int len):
   将字节数组b中第off+1个元素开始的len个数据,顺序地写人到输出流
public void flush():
    强制清空缓冲区并执行向外设写操作
public void close():
    关闭输出流与外设的连接并释放所占用的系统资源  

常见的InputStream和OutputStream实现类

网络数据传输:
    SocketInputStream 和 SocketOutputStream
文件操作:
    FileInputStream 和 FileOutputStream
字节数据操作:
    DataInputStream 和 DataOutputStream

InputStream源码分析

package java.io;
public abstract class InputStream implements Closeable {

    //MAX_SKIP_BUFFER_SIZE用于确定最大缓冲区大小
    //在跳过时使用  
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;

    //从输入流中读取下一个byte的数据,返回的是一个0~255之间的int类型数。
    //如果已经到了流的末尾没有byte数据那么返回-1。
    //此方法阻塞,直到输入数据可用、检测到流的末尾或抛出异常。
    public abstract int read() throws IOException;

    //从输入流中读取一些字节,并将其存储到缓冲区数组b。
    //实际读取的字节数是以整数形式返回。此方法将阻塞,知道输入数据为止可用,检测到文件结尾,或抛出异常。
    //如果b的长度为0,则不读取任何字节,返回0。如果没有可用的字节,因为流是在文件结尾,返回值-1.
    //读取的字节数是:最多读取b的长度。
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

    //从输入流中读取长度len的byte数据到一个数组中。
    //尝试尽可能的读取len长度的byte,但是可能读取较小的长度内荣,返回的是实际获取到的数据长度。
    public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            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;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }

    //从输入流中跳过和丢弃n个byte数据。
    //返回实际丢弃的数据长度。
    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) {
            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 {}

    //标记输入流当前的位置,随后调用reset放在在最后的标记位置重新定位,以便后续读取相同的字节。
    //readlimit 参数标识此输入流允许在标记失效为止之前获取的字节数。
    public synchronized void mark(int readlimit) {}

    //将此输入流重新定位到上次调用mark方法标记的地方。
    //如果markSupported方法返回true,或者自从上次标记之后从该输入流中读取的数据大于标记的长度可能会抛出IOException。
    //如果markSupported方法返回false,那么调用改方法可能抛出IOException。
    public synchronized void reset() throws IOException {
        throw new IOException("mark/reset not supported");
    }

    // 测试这个输入流是否支持标记和充值。
    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;

    // 从指定的byte数组中写入到该输出流
    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }

    //从byte数组的off开始,想输出流中写入len长度的数据。可能空指针和数据越界异常。
    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 {
    }
}
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaCourse/202301/5347.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者