zoukankan      html  css  js  c++  java
  • 从构造函数看java.io

    package java.io;

    interface有Closeable、Flushable

    abstract class 有InputStream、OutputStream、Reader、Writer

    class有InputStreamReader、OutputStreamWriter,FileReader、FileWriter

    ----------------------------

    InputStream是所有字节输入流的父类

    package java.io;
    
    /**
     * This abstract class is the superclass of all classes representing
     * an input stream of bytes.
     *
     * <p> Applications that need to define a subclass of <code>InputStream</code>
     * must always provide a method that returns the next byte of input.
     *
     * @author  Arthur van Hoff
     * @see     java.io.BufferedInputStream
     * @see     java.io.ByteArrayInputStream
     * @see     java.io.DataInputStream
     * @see     java.io.FilterInputStream
     * @see     java.io.InputStream#read()
     * @see     java.io.OutputStream
     * @see     java.io.PushbackInputStream
     * @since   JDK1.0
     */
    public abstract class InputStream implements Closeable {

    内部有一个抽象函数。read方法会阻塞,除非:1输入数据可获得,2流读完了,3发生io异常。read的返回值是一个0-255的int,表示一个byte

     /**
         * 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;

    对应的,OutputStream是字节输出流的父类,有一个write抽象函数。参数int中的低8位会被写入输出流,高24位会被忽略。

     /**
         * Writes the specified byte to this output stream. The general
         * contract for <code>write</code> is that one byte is written
         * to the output stream. The byte to be written is the eight
         * low-order bits of the argument <code>b</code>. The 24
         * high-order bits of <code>b</code> are ignored.
         * <p>
         * Subclasses of <code>OutputStream</code> must provide an
         * implementation for this method.
         *
         * @param      b   the <code>byte</code>.
         * @exception  IOException  if an I/O error occurs. In particular,
         *             an <code>IOException</code> may be thrown if the
         *             output stream has been closed.
         */
        public abstract void write(int b) throws IOException;

    FileInputStream直接继承了InputStream,被设计用来读取二进制字节流文件,例如图片。其中read间接调用了本地函数

    /**
     * A <code>FileInputStream</code> obtains input bytes
     * from a file in a file system. What files
     * are  available depends on the host environment.
     *
     * <p><code>FileInputStream</code> is meant for reading streams of raw bytes
     * such as image data. For reading streams of characters, consider using
     * <code>FileReader</code>.
     *
     * @author  Arthur van Hoff
     * @see     java.io.File
     * @see     java.io.FileDescriptor
     * @see     java.io.FileOutputStream
     * @see     java.nio.file.Files#newInputStream
     * @since   JDK1.0
     */
    public
    class FileInputStream extends InputStream
    --------------------------------------
    /**
         * Reads a byte of data from this input stream. This method blocks
         * if no input is yet available.
         *
         * @return     the next byte of data, or <code>-1</code> if the end of the
         *             file is reached.
         * @exception  IOException  if an I/O error occurs.
         */
        public int read() throws IOException {
            return read0();
        }
    
        private native int read0() throws IOException;

    它有三个构造函数public FileInputStream(String)间接调用了public FileInputStream(File)。

     public FileInputStream(String name) throws FileNotFoundException {
            this(name != null ? new File(name) : null);
        }
      public FileInputStream(File file) throws FileNotFoundException {
            String name = (file != null ? file.getPath() : null);
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkRead(name);
            }
            if (name == null) {
                throw new NullPointerException();
            }
            if (file.isInvalid()) {
                throw new FileNotFoundException("Invalid file path");
            }
            fd = new FileDescriptor();
            fd.attach(this);
            path = name;
            open(name);
        }
     public FileInputStream(FileDescriptor fdObj) {
            SecurityManager security = System.getSecurityManager();
            if (fdObj == null) {
                throw new NullPointerException();
            }
            if (security != null) {
                security.checkRead(fdObj);
            }
            fd = fdObj;
            path = null;
    
            /*
             * FileDescriptor is being shared by streams.
             * Register this stream with FileDescriptor tracker.
             */
            fd.attach(this);
        }

    看一下java.io.File;

    首先,类注释明确指出了java.io.File是文件和文件夹的抽象表示,不单单是文件哦!

    /**
     * An abstract representation of file and directory pathnames.
     *
    public class File
        implements Serializable, Comparable<File>
    {

    --------------------------

    看字符流吧

    BufferedReader是直接继承自Reader的字符流,并且自带缓冲。缓冲区大小可以指定,不指定采用默认值8192

    /**
     * Reads text from a character-input stream, buffering characters so as to
     * provide for the efficient reading of characters, arrays, and lines.
     *
     * <p> The buffer size may be specified, or the default size may be used.  The
     * default is large enough for most purposes.
     **/
    
    public class BufferedReader extends Reader {

    构造函数有两个,BufferedReader(Reader)调用BufferedReader(Reader,int),其中defaultCharBufferSize=8192;

    需要注意的是,BufferedReader作为一个Reader,本身需要外部的Reader作为参数,我想到了装饰模式。

    BufferedReader是一个Reader但是本身不完整,它本质是对Reader做了装饰。

     /**
         * Creates a buffering character-input stream that uses an input buffer of
         * the specified size.
         *
         * @param  in   A Reader
         * @param  sz   Input-buffer size
         *
         * @exception  IllegalArgumentException  If {@code sz <= 0}
         */
        public BufferedReader(Reader in, int sz) {
            super(in);
            if (sz <= 0)
                throw new IllegalArgumentException("Buffer size <= 0");
            this.in = in;
            cb = new char[sz];
            nextChar = nChars = 0;
        }
    
        /**
         * Creates a buffering character-input stream that uses a default-sized
         * input buffer.
         *
         * @param  in   A Reader
         */
        public BufferedReader(Reader in) {
            this(in, defaultCharBufferSize);
        }

    BufferedInputStream也是一样,不同的是BufferedInputStream继承InputStream,是对字节流的装饰。并且BufferedInputStream提供了对mark和reset的支持。

    /**
     * A <code>BufferedInputStream</code> adds
     * functionality to another input stream-namely,
     * the ability to buffer the input and to
     * support the <code>mark</code> and <code>reset</code>
     * methods. When  the <code>BufferedInputStream</code>
     * is created, an internal buffer array is
     * created. As bytes  from the stream are read
     * or skipped, the internal buffer is refilled
     * as necessary  from the contained input stream,
     * many bytes at a time. The <code>mark</code>
     * operation  remembers a point in the input
     * stream and the <code>reset</code> operation
     * causes all the  bytes read since the most
     * recent <code>mark</code> operation to be
     * reread before new bytes are  taken from
     * the contained input stream.
     *
     * @author  Arthur van Hoff
     * @since   JDK1.0
     */
    public
    class BufferedInputStream extends FilterInputStream {

    构造函数如下

    /**
         * Creates a <code>BufferedInputStream</code>
         * and saves its  argument, the input stream
         * <code>in</code>, for later use. An internal
         * buffer array is created and  stored in <code>buf</code>.
         *
         * @param   in   the underlying input stream.
         */
        public BufferedInputStream(InputStream in) {
            this(in, DEFAULT_BUFFER_SIZE);
        }
    
        /**
         * Creates a <code>BufferedInputStream</code>
         * with the specified buffer size,
         * and saves its  argument, the input stream
         * <code>in</code>, for later use.  An internal
         * buffer array of length  <code>size</code>
         * is created and stored in <code>buf</code>.
         *
         * @param   in     the underlying input stream.
         * @param   size   the buffer size.
         * @exception IllegalArgumentException if {@code size <= 0}.
         */
        public BufferedInputStream(InputStream in, int size) {
            super(in);
            if (size <= 0) {
                throw new IllegalArgumentException("Buffer size <= 0");
            }
            buf = new byte[size];
        }

    -----------------------

    从字节流到字符流的桥梁

    InputStreamReader继承自Reader,它的主要工作是将字节流解码成字符流。

    InputStreamReader里面有一个变量StreamDecoder sd,实际工作其实都是有这个sd来做的。说不出来这是什么模式,但不是代理模式。sun.nio.cs.StreamDecoder的源码没有找到。

    /**
     * An InputStreamReader is a bridge from byte streams to character streams: It
     * reads bytes and decodes them into characters using a specified {@link
     * java.nio.charset.Charset charset}.  The charset that it uses
     * may be specified by name or may be given explicitly, or the platform's
     * default charset may be accepted.
     *
     * <p> Each invocation of one of an InputStreamReader's read() methods may
     * cause one or more bytes to be read from the underlying byte-input stream.
     * To enable the efficient conversion of bytes to characters, more bytes may
     * be read ahead from the underlying stream than are necessary to satisfy the
     * current read operation.
     *
     * <p> For top efficiency, consider wrapping an InputStreamReader within a
     * BufferedReader.  For example:
     *
     * <pre>
     * BufferedReader in
     *   = new BufferedReader(new InputStreamReader(System.in));
     * </pre>
     *
     * @see BufferedReader
     * @see InputStream
     * @see java.nio.charset.Charset
     *
     * @author      Mark Reinhold
     * @since       JDK1.1
     */
    
    public class InputStreamReader extends Reader {
    private final StreamDecoder sd;

    其构造函数如下

     /**
         * Creates an InputStreamReader that uses the default charset.
         *
         * @param  in   An InputStream
         */
        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);
            }
        }
    
        /**
         * Creates an InputStreamReader that uses the named charset.
         *
         * @param  in
         *         An InputStream
         *
         * @param  charsetName
         *         The name of a supported
         *         {@link java.nio.charset.Charset charset}
         *
         * @exception  UnsupportedEncodingException
         *             If the named charset is not supported
         */
        public InputStreamReader(InputStream in, String charsetName)
            throws UnsupportedEncodingException
        {
            super(in);
            if (charsetName == null)
                throw new NullPointerException("charsetName");
            sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
        }
    
        /**
         * Creates an InputStreamReader that uses the given charset.
         *
         * @param  in       An InputStream
         * @param  cs       A charset
         *
         * @since 1.4
         * @spec JSR-51
         */
        public InputStreamReader(InputStream in, Charset cs) {
            super(in);
            if (cs == null)
                throw new NullPointerException("charset");
            sd = StreamDecoder.forInputStreamReader(in, this, cs);
        }
    
        /**
         * Creates an InputStreamReader that uses the given charset decoder.
         *
         * @param  in       An InputStream
         * @param  dec      A charset decoder
         *
         * @since 1.4
         * @spec JSR-51
         */
        public InputStreamReader(InputStream in, CharsetDecoder dec) {
            super(in);
            if (dec == null)
                throw new NullPointerException("charset decoder");
            sd = StreamDecoder.forInputStreamReader(in, this, dec);
        }

    这四个构造函数都是调用了StreamDecoder.forInputStreamReader函数

    ----------------------------

    总结一下,在这几个常用的io流中,本质上说程序员只能从文件构造流,或者使用外部提供的流,例如System.in,socket.getInputStream;

    其他的类都是对流的装饰。

  • 相关阅读:
    hdoj2187:悼念512汶川大地震遇难同胞 (贪心)
    2.0其它之Transform详解,以及UIElement和FrameworkElement的常用属性
    2.0外观之样式, 模板, 视觉状态和视觉状态管理器
    2.0图形之Ellipse, Line, Path, Polygon, Polyline, Rectangle
    2.0控件之ListBox, MediaElement, MultiScaleImage, PasswordBox, ProgressBar, RadioButton
    2.0画笔之SolidColorBrush, ImageBrush, VideoBrush, LinearGradientBrush, RadialGradientBrush
    2.0图形之基类System.Windows.Shapes.Shape
    2.0交互之鼠标事件和键盘事件
    2.0控件之ScrollViewer, Slider, StackPanel, TabControl, TextBlock, TextBox, ToggleButton
    2.0交互之InkPresenter(涂鸦板)
  • 原文地址:https://www.cnblogs.com/afraidToForget/p/6623503.html
Copyright © 2011-2022 走看看