`
seraphim.leo
  • 浏览: 24108 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java I/O 系统 (二)

阅读更多

输入输出

 

编程语言的I/O类库中常使用这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象。“”屏蔽了实际的I/O设备中处理数据的细节。

 

Java类库中的I/O类分成输入和输出两部分。通过继承,任何自Inputstream或Reader派生而来的类都含有名为read()的基本方法,用于读取单个字节或者字节数组。同样,任何自Outputstream或Writer派生而来的类都含有名为write()的基本方法,用于写单个字节或者字节数组。但是,我们通常不会用到这些方法,它们之所以存在是因为别的类可以使用它们,以便提供更有用的接口。因此,我们很少使用单一的类来创建流对象,而是通过叠合多个对象来提供所期望的功能。

 

实际上,Java中,“”类库让人迷惑的主要原因就在于:创建单一的结果流,却需要创建多个对象。

 

 

一、InputStream类型

InputStream的作用是用来表示那些从不同数据源产生输入的类,这些数据源包括:

 

  1. 字节数组
  2. String对象
  3. 文件
  4. “管道”,工作方式与实际管道相似,即,从一段输入,从另一端输出。
  5. 一个由其他种类的流组成的序列。
  6. 其他数据源。
每一种数据源都有相应的InputStream子类

二、OutputStream类型
该类别的类决定了输出所要去往的目标:字节数组,文件或管道。


 

 

 

 

InputStream部分源码分析

 

 

/**
     * Reads the next byte of data from the input stream. The value byte is
     * returned as an <code>int</code> in the range <code>0</code> to
     * <code>255</code>. If no byte is available because the end of the stream
     * has been reached, the value <code>-1</code> is returned. This method
     * blocks until input data is available, the end of the stream is detected,
     * or an exception is thrown.
     *
     * <p> A subclass must provide an implementation of this method.
     *
     * @return     the next byte of data, or <code>-1</code> if the end of the
     *             stream is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public abstract int read() throws IOException;

    /**
     * Reads some number of bytes from the input stream and stores them into
     * the buffer array <code>b</code>. The number of bytes actually read is
     * returned as an integer.  This method blocks until input data is
     * available, end of file is detected, or an exception is thrown.
     *
     * <p> If the length of <code>b</code> is zero, then no bytes are read and
     * <code>0</code> is returned; otherwise, there is an attempt to read at
     * least one byte. If no byte is available because the stream is at the
     * end of the file, the value <code>-1</code> is returned; otherwise, at
     * least one byte is read and stored into <code>b</code>.
     *
     * <p> The first byte read is stored into element <code>b[0]</code>, the
     * next one into <code>b[1]</code>, and so on. The number of bytes read is,
     * at most, equal to the length of <code>b</code>. Let <i>k</i> be the
     * number of bytes actually read; these bytes will be stored in elements
     * <code>b[0]</code> through <code>b[</code><i>k</i><code>-1]</code>,
     * leaving elements <code>b[</code><i>k</i><code>]</code> through
     * <code>b[b.length-1]</code> unaffected.
     *
     * <p> The <code>read(b)</code> method for class <code>InputStream</code>
     * has the same effect as: <pre><code> read(b, 0, b.length) </code></pre>
     *
     * @param      b   the buffer into which the data is read.
     * @return     the total number of bytes read into the buffer, or
     *             <code>-1</code> is there is no more data because the end of
     *             the stream has been reached.
     * @exception  IOException  If the first byte cannot be read for any reason
     * other than the end of the file, if the input stream has been closed, or
     * if some other I/O error occurs.
     * @exception  NullPointerException  if <code>b</code> is <code>null</code>.
     * @see        java.io.InputStream#read(byte[], int, int)
     */
    public int read(byte b[]) throws IOException {
	return read(b, 0, b.length);
    }

    /**
     * Reads up to <code>len</code> bytes of data from the input stream into
     * an array of bytes.  An attempt is made to read as many as
     * <code>len</code> bytes, but a smaller number may be read.
     * The number of bytes actually read is returned as an integer.
     *
     * <p> This method blocks until input data is available, end of file is
     * detected, or an exception is thrown.
     *
     * <p> If <code>len</code> is zero, then no bytes are read and
     * <code>0</code> is returned; otherwise, there is an attempt to read at
     * least one byte. If no byte is available because the stream is at end of
     * file, the value <code>-1</code> is returned; otherwise, at least one
     * byte is read and stored into <code>b</code>.
     *
     * <p> The first byte read is stored into element <code>b[off]</code>, the
     * next one into <code>b[off+1]</code>, and so on. The number of bytes read
     * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
     * bytes actually read; these bytes will be stored in elements
     * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
     * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
     * <code>b[off+len-1]</code> unaffected.
     *
     * <p> In every case, elements <code>b[0]</code> through
     * <code>b[off]</code> and elements <code>b[off+len]</code> through
     * <code>b[b.length-1]</code> are unaffected.
     *
     * <p> The <code>read(b,</code> <code>off,</code> <code>len)</code> method
     * for class <code>InputStream</code> simply calls the method
     * <code>read()</code> repeatedly. If the first such call results in an
     * <code>IOException</code>, that exception is returned from the call to
     * the <code>read(b,</code> <code>off,</code> <code>len)</code> method.  If
     * any subsequent call to <code>read()</code> results in a
     * <code>IOException</code>, the exception is caught and treated as if it
     * were end of file; the bytes read up to that point are stored into
     * <code>b</code> and the number of bytes read before the exception
     * occurred is returned. The default implementation of this method blocks
     * until the requested amount of input data <code>len</code> has been read,
     * end of file is detected, or an exception is thrown. Subclasses are encouraged
     * to provide a more efficient implementation of this method.
     *
     * @param      b     the buffer into which the data is read.
     * @param      off   the start offset in array <code>b</code>
     *                   at which the data is written.
     * @param      len   the maximum number of bytes to read.
     * @return     the total number of bytes read into the buffer, or
     *             <code>-1</code> if there is no more data because the end of
     *             the stream has been reached.
     * @exception  IOException If the first byte cannot be read for any reason
     * other than end of file, or if the input stream has been closed, or if
     * some other I/O error occurs.
     * @exception  NullPointerException If <code>b</code> is <code>null</code>.
     * @exception  IndexOutOfBoundsException If <code>off</code> is negative, 
     * <code>len</code> is negative, or <code>len</code> is greater than 
     * <code>b.length - off</code>
     * @see        java.io.InputStream#read()
     */
    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;
    }

 

 

我们看到,read()方法实际上是一个抽象方法,需要每个继承InputStream的子类来进行覆盖,举例来说,我们在FileInputStream中看到,read()方法是这样写的:

 

 

    /**
     * Reads a subarray as a sequence of bytes.
     * @param b the data to be written
     * @param off the start offset in the data
     * @param len the number of bytes that are written
     * @exception IOException If an I/O error has occurred.
     */
    private native int readBytes(byte b[], int off, int len) throws IOException;

 

 

也就是说,这里读取字节的方法,并不是使用Java语言编写,而是写在了更底层的代码中。而在ByteArrayInputStream类中,read()方法是这样实现的:

 

 

    /**
     * Reads the next byte of data from this input stream. The value 
     * byte is returned as an <code>int</code> in the range 
     * <code>0</code> to <code>255</code>. If no byte is available 
     * because the end of the stream has been reached, the value 
     * <code>-1</code> is returned. 
     * <p>
     * This <code>read</code> method 
     * cannot block. 
     *
     * @return  the next byte of data, or <code>-1</code> if the end of the
     *          stream has been reached.
     */
    public synchronized int read() {
	return (pos < count) ? (buf[pos++] & 0xff) : -1;
    }

 

 

继续回到InputStream类中,该类的其他两个read方法,read(byte [] b) 和 read(byte [] b , int off , int len)方法,这两个方法的实现根本上是调用了read(),而真正的read()实现又出现在其子类中,这样的做法使得读取不同类型的流时,提供了很大的灵活性,值得我们学习。

分享到:
评论

相关推荐

    java数据流 I/O系统

    描述java的I/o系统,描述了java中文件系统的处理,数据流的处理

    Java I/O学习笔记: 磁盘操作 字节操作 字符操作 对象操作 网络操作 NIO & AIO Java I/O

    Java I/O学习笔记: 磁盘操作 字节操作 字符操作 对象操作 网络操作 NIO & AIO Java I/O Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,意味着可以在不同的操作系统上运行...

    java I/O类的使用

    简单介绍了java 的输入输出系统中类的使用,java1.0和java1.1中的类的来源去向

    Java I/O系统

    NULL 博文链接:https://xace.iteye.com/blog/703920

    基于I/O、多线程、GUI的标准考试系统v1.0(JAVA实现)

    本系统是基于JAVA开发平台,运用Socket网络编程,I/O文件流,线程,Swing图形界面等技术,实现的一套标准化考试系统。通过该系统可以完成多个科目的标准化考试工作。 该系统共分为三个模块:考生客户端,服务器端和...

    探索Java I/O 模型的演进

    什么是同步?什么是异步?阻塞和非阻塞又有什么区别?本文先从 Unix 的 I/O ...而后再引出 Java 的 I/O 模型的演进过程,并用实例说明如何选择合适的 Java I/O 模型来提高系统的并发量和可用性。,需要的朋友可以参考下

    java使用简单的I/O编写的投票系统

    java使用简单的I/O编写的投票系统

    Java I/O底层是如何工作的?

    本博文主要讨论I/O在底层是如何工作的。本文服务的读者,迫切希望了解Java I/O操作是在机器层面如何进行映射,以及应用运行时硬件都做了什么。...通常,进程执行操作系统的I/O请求包括数据从缓冲区排

    彻底明白 Java 语言中的IO系统

    彻底明白 Java 语言中的IO系统 彻底明白 Java 语言中的IO系统

    Java I/O深入学习之File和RandomAccessFile

    主要介绍了Java I/O深入学习之File和RandomAccessFile, I/O系统即输入/输出系统,对于一门程序语言来说,创建一个好的输入/输出系统并非易事。在充分理解Java I/O系统以便正确地运用之前,我们需要学习相当数量的...

    java nio超好资源

    NIO 的创建目的是为了让 Java 程序员可以实现高速 I/O 而无需编写自定义的本机代码。NIO 将最耗时的 I/O 操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度。

    java_I/ODemo

    对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务,在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是...

    java基础知识I/O流使用详解

    编程语言的I/O类库中常常使用流这个抽象的概念,它代表任何有能力产生数据的数据源对象或时有能力接收数据的接收端对象,本文为大家介绍Java中I/O系统基础知识

    基于I/O流设计的图书馆管理系统

    这个是我基于I/O流设计的图书馆管理系统项目总结,是有篇文章的,如果实在不会整再来下载这个完整的。文章:https://blog.csdn.net/GB__LaoWang/article/details/115914058

    使用Java实现一个简单的文件管理系统.txt

    这段代码实现了一个简单的文件管理系统,其中使用了Java的I/O类库。在类的构造方法中,首先创建了一个File对象来表示要操作的文件,如果该文件不存在则创建新文件。然后通过FileReader和BufferedReader类来读取文件...

    彻底明白 Java 语言中的IO系统 .pdf

    彻底明白 Java 语言中的IO系统 .pdf

    基于java NIO的简单聊天软件示例

    JAVA NIO有两种解释:一种叫非阻塞IO(Non-blocking I/O),另一种也叫新的IO(New I/O),其实是同一个概念。它是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为...

    彻底明白Java的IO系统

    彻底明白Java的IO系统,知道I/O内部运行机制。

    Thinking in Java 4th Edition(中文扫描版-带目录和源码)

    本书共22章,包括操作符、控制执行流程、访问权限控制、复用类、多态、接口、通过异常处理错误、字符串、泛型、数组、容器深入研究、JavaI/O系统、枚举类型、并发以及图形化用户界面等内容。这些丰富的内容,包含了...

    Java实现的小型文件管理系统

    文件批量处理用(Eclipse)Java实现,模块为了方便管理文件而设计,通过本模块可以快速地实现文件的批量复制、批量删除、批量重命名、文件分类等。内含设计文档,包括使用说明。还有打包好的可运行的jar文件。

Global site tag (gtag.js) - Google Analytics