# io

#

  • 代表有能力产出数据的数据源对象,或者有能力接受数据的接收端对象.
  • 其本质是数据传输,它的作用是为数据源和目的地建立一个传输通道

# java流的分类

  • 数据类型维度
    • 字符流
    • 字节流
  • 数据流向维度
    • 输入流
    • 输出流

# 输入流

# 意义

  • 数据读取操作

# 顶级抽象结构

  • 字节输入流
public abstract class InputStream implements Closeable {
    public abstract int read() throws IOException;

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

    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;
        }

    //省略其它抽象...
}
  • 字符输入流
public interface Readable {
    public int read(java.nio.CharBuffer cb) throws IOException;
}
public abstract class Reader implements Readable, Closeable {

     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;
     
    //省略其它抽象...
}

# 常见实现

  • 字节输入流
public class ByteArrayInputStream extends InputStream {

    protected byte buf[];

    protected int pos;   

    protected int count;

    public synchronized int read() {
            return (pos < count) ? (buf[pos++] & 0xff) : -1;
    }

    public ByteArrayInputStream(byte buf[]) {
            this.buf = buf;
            this.pos = 0;
            this.count = buf.length;
        }
    
    //省略其它抽象...
}
  • 字节输入流(带缓存)
public class FilterInputStream extends InputStream {
    protected volatile InputStream in;

    protected FilterInputStream(InputStream in) {
            this.in = in;
        }

    //省略其它抽象...
}

public class BufferedInputStream extends FilterInputStream {
    private static int DEFAULT_BUFFER_SIZE = 8192;

    private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;

    protected volatile byte buf[];

    protected int count;

    protected int pos;

    protected int markpos = -1;

    public BufferedInputStream(InputStream in) {
            this(in, DEFAULT_BUFFER_SIZE);
        }
        
    public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

    public synchronized int read() throws IOException {
            if (pos >= count) {
                fill();
                if (pos >= count)
                    return -1;
            }
            return getBufIfOpen()[pos++] & 0xff;
    }

    private void fill() throws IOException {
            byte[] buffer = getBufIfOpen();
            if (markpos < 0)
                pos = 0;            /* no mark: throw away the buffer */
            else if (pos >= buffer.length)  /* no room left in buffer */
                if (markpos > 0) {  /* can throw away early part of the buffer */
                    int sz = pos - markpos;
                    System.arraycopy(buffer, markpos, buffer, 0, sz);
                    pos = sz;
                    markpos = 0;
                } else if (buffer.length >= marklimit) {
                    markpos = -1;   /* buffer got too big, invalidate mark */
                    pos = 0;        /* drop buffer contents */
                } else if (buffer.length >= MAX_BUFFER_SIZE) {
                    throw new OutOfMemoryError("Required array size too large");
                } else {            /* grow buffer */
                    int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
                            pos * 2 : MAX_BUFFER_SIZE;
                    if (nsz > marklimit)
                        nsz = marklimit;
                    byte nbuf[] = new byte[nsz];
                    System.arraycopy(buffer, 0, nbuf, 0, pos);
                    if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
                        throw new IOException("Stream closed");
                    }
                    buffer = nbuf;
                }
            count = pos;
            int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
            if (n > 0)
                count = n + pos;
    }

     private InputStream getInIfOpen() throws IOException {
            InputStream input = in;
            if (input == null)
                throw new IOException("Stream closed");
            return input;
     }

     private byte[] getBufIfOpen() throws IOException {
             byte[] buffer = buf;
             if (buffer == null)
                 throw new IOException("Stream closed");
             return buffer;
     }

    //省略其它抽象...
}

  • 字符输入流
public class InputStreamReader extends Reader {
    private final StreamDecoder sd;

    //StreamDecoder由 sun提供,屏蔽了实现的复杂性
    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);
            }
        }

    public InputStreamReader(InputStream in, String charsetName)
            throws UnsupportedEncodingException
        {
            super(in);
            if (charsetName == null)
                throw new NullPointerException("charsetName");
            sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }

    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 class BufferedReader extends Reader {
    private Reader in;

    private char cb[];
    private int nChars, nextChar;

     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;
     }

    public BufferedReader(Reader in) {
            this(in, defaultCharBufferSize);
    }

    public int read() throws IOException {
            synchronized (lock) {
                ensureOpen();
                for (;;) {
                    if (nextChar >= nChars) {
                        fill();
                        if (nextChar >= nChars)
                            return -1;
                    }
                    if (skipLF) {
                        skipLF = false;
                        if (cb[nextChar] == '\n') {
                            nextChar++;
                            continue;
                        }
                    }
                    return cb[nextChar++];
                }
            }
    }


    private void fill() throws IOException {
            int dst;
            if (markedChar <= UNMARKED) {
                /* No mark */
                dst = 0;
            } else {
                /* Marked */
                int delta = nextChar - markedChar;
                if (delta >= readAheadLimit) {
                    /* Gone past read-ahead limit: Invalidate mark */
                    markedChar = INVALIDATED;
                    readAheadLimit = 0;
                    dst = 0;
                } else {
                    if (readAheadLimit <= cb.length) {
                        /* Shuffle in the current buffer */
                        System.arraycopy(cb, markedChar, cb, 0, delta);
                        markedChar = 0;
                        dst = delta;
                    } else {
                        /* Reallocate buffer to accommodate read-ahead limit */
                        char ncb[] = new char[readAheadLimit];
                        System.arraycopy(cb, markedChar, ncb, 0, delta);
                        cb = ncb;
                        markedChar = 0;
                        dst = delta;
                    }
                    nextChar = nChars = delta;
                }
            }
    
            int n;
            do {
                n = in.read(cb, dst, cb.length - dst);
            } while (n == 0);
            if (n > 0) {
                nChars = dst + n;
                nextChar = dst;
            }
    }

    //省略其它抽象
   
}

# 输出流

# 意义

数据保存操作

# 顶级抽象结构

  • 字节输出流
public interface Flushable {
    void flush() throws IOException;
}

public abstract class OutputStream implements Closeable, Flushable {

    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 interface Appendable {
    Appendable append(CharSequence csq, int start, int end) throws IOException;
    //省略其它抽象...
}

public abstract class Writer implements Appendable, Closeable, Flushable {

    private char[] writeBuffer;

    protected Object lock;

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

    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(String str) throws IOException {
            write(str, 0, str.length());
    }

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

    //省略其它抽象...
}

# 常见实现

  • 字节输出流
public class ByteArrayOutputStream extends OutputStream {

   protected byte buf[];

   protected int count;

   public ByteArrayOutputStream(int size) {
           if (size < 0) {
               throw new IllegalArgumentException("Negative initial size: "
                                                  + size);
           }
           buf = new byte[size];
   }

   public synchronized void write(int b) {
           ensureCapacity(count + 1);
           buf[count] = (byte) b;
           count += 1;
   }

   private void ensureCapacity(int minCapacity) {
           // overflow-conscious code
           if (minCapacity - buf.length > 0)
               grow(minCapacity);
   }
 
   private void grow(int minCapacity) {
           // overflow-conscious code
           int oldCapacity = buf.length;
           int newCapacity = oldCapacity << 1;
           if (newCapacity - minCapacity < 0)
               newCapacity = minCapacity;
           if (newCapacity - MAX_ARRAY_SIZE > 0)
               newCapacity = hugeCapacity(minCapacity);
           buf = Arrays.copyOf(buf, newCapacity);
       }
   
   private static int hugeCapacity(int minCapacity) {
           if (minCapacity < 0) // overflow
               throw new OutOfMemoryError();
           return (minCapacity > MAX_ARRAY_SIZE) ?
               Integer.MAX_VALUE :
               MAX_ARRAY_SIZE;
   }

    //省略其它抽象...
}
  • 字节输出流(带缓存)
public class BufferedOutputStream extends FilterOutputStream {
    
    protected byte buf[];

    protected int count;

    public BufferedOutputStream(OutputStream out) {
            this(out, 8192);
    }

    public BufferedOutputStream(OutputStream out, int size) {
            super(out);
            if (size <= 0) {
                throw new IllegalArgumentException("Buffer size <= 0");
            }
            buf = new byte[size];
    }

    public synchronized void write(int b) throws IOException {
            if (count >= buf.length) {
                flushBuffer();
            }
            buf[count++] = (byte)b;
        }

    private void flushBuffer() throws IOException {
            if (count > 0) {
                out.write(buf, 0, count);
                count = 0;
            }
    }

    public synchronized void write(byte b[], int off, int len) throws IOException {
            if (len >= buf.length) {
                /* If the request length exceeds the size of the output buffer,
                   flush the output buffer and then write the data directly.
                   In this way buffered streams will cascade harmlessly. */
                flushBuffer();
                out.write(b, off, len);
                return;
            }
            if (len > buf.length - count) {
                flushBuffer();
            }
            System.arraycopy(b, off, buf, count, len);
            count += len;
    }

    //省略其它抽象...
}
  • 字符输出流
public class OutputStreamWriter extends Writer {

    //由sun提供实现
    private final StreamEncoder se;
    
    public OutputStreamWriter(OutputStream out, String charsetName)
            throws UnsupportedEncodingException
        {
            super(out);
            if (charsetName == null)
                throw new NullPointerException("charsetName");
            se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
    } 

    public OutputStreamWriter(OutputStream out, Charset cs) {
            super(out);
            if (cs == null)
                throw new NullPointerException("charset");
            se = StreamEncoder.forOutputStreamWriter(out, this, cs);
    }

    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 class BufferedWriter extends Writer {
    private Writer out;

    private char cb[];
    private int nChars, nextChar;

    private static int defaultCharBufferSize = 8192;

    private String lineSeparator;

    public BufferedWriter(Writer out) {
            this(out, defaultCharBufferSize);
    }

    public BufferedWriter(Writer out, int sz) {
            super(out);
            if (sz <= 0)
                throw new IllegalArgumentException("Buffer size <= 0");
            this.out = out;
            cb = new char[sz];
            nChars = sz;
            nextChar = 0;
    
            lineSeparator = java.security.AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction("line.separator"));
    }

    public void write(int c) throws IOException {
            synchronized (lock) {
                ensureOpen();
                if (nextChar >= nChars)
                    flushBuffer();
                cb[nextChar++] = (char) c;
            }
    }

     void flushBuffer() throws IOException {
            synchronized (lock) {
                ensureOpen();
                if (nextChar == 0)
                    return;
                out.write(cb, 0, nextChar);
                nextChar = 0;
            }
     }

    private void ensureOpen() throws IOException {
            if (out == null)
                throw new IOException("Stream closed");
        }

    //省略其它抽象...
}

# java中常见读写介质

# 屏幕读写

  • 写入屏幕
public class Test {
    public static void main(String[] args) throws IOException {
       System.out.println("hello,world!");
    }
}
  • 屏幕读取
public class Test {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println(scanner.next());
    }
}

public class Test {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println(bufferedReader.readLine());
    }
}

# 文件读写

  • 写入文件
public class Test {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream  = new FileOutputStream("D:\\mytest\\myFile.txt");
        fileOutputStream.write("hello,automann!".getBytes());
    }
}
  • 文件读取
public class Test {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream  = new FileInputStream("D:\\mytest\\myFile.txt");
        byte[] result = new byte[fileInputStream.available()];
        fileInputStream.read(result);
        System.out.println(new String(result));
    }
}

# 内存读写

  • 写入内存
public class Test {
    public static void main(String[] args) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream  = new ByteArrayOutputStream();
        byteArrayOutputStream.write("hello,the beautiful life.".getBytes());
    }
}
  • 内存读取
public class Test {
    public static void main(String[] args) throws IOException {

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("hello,the beautiful life.".getBytes());
        byte[] result = new byte[byteArrayInputStream.available()];
        byteArrayInputStream.read(result);
        System.out.println(new String(result));
    }
}

# commons-io读写工具类

  • 流拷贝
public class Test {
    public static void main(String[] args) throws IOException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("hello,the beautiful life.".getBytes());
        IOUtils.copy(byteArrayInputStream,System.out);
    }
}