InputStream、OutputStream、BufferedOutputStream源码解析

The InputStream/OutputStream works with Bytes which are 8 bits.
read、write根上调用的是native方法

一、read

1.方法

/*
Reads a byte of data from this input stream.
@return:next byte of data(0-255),or -1 if end
*/
int read()

/*
Reads up to b.length bytes of data from this input stream into an array of bytes
@param:b the buffer into which the data is read.
@return:the total number of bytes read into the buffer(0-Integer.MAX_VALUE),
or -1
*/
int read(byte[] b)

/*
Reads up to len bytes of data from this input stream into an array of bytes
@param b:the buffer into which the data is read.
@param off:the start offset in the destination array b
@param len:the maximum number of bytes read.
@return:the total number of bytes read into the buffer(0-Integer.MAX_VALUE),
or -1
*/
int read(byte[] b,int off,int len)

 /*
Returns an estimate of the number of remaining bytes that can be read (or
skipped over) from this input stream  
@return:an estimate of the number of remaining bytes that can be read
(or skipped over) from this input stream without blocking.
 */
int available()

/*
Closes this file input stream and releases any system resources
associated with the stream.
*/
void close()

2.实例

在这里插入图片描述

//读
		FileInputStream fis=new FileInputStream("fos.txt");
		
		System.out.println("-----------读的第一种方法----------");
		//一个字节一个字节的读:read()方法
		/*int num=0;
		while ((num=fis.read())!=-1) {
			System.out.println((char)num);
		}
		fis.close();
		*/
		
		System.out.println("-----------读的第二种方法----------");
		//字节数组的读read(byte[] b)
		/*byte[] buf=new byte[1024];
		int len=0;
		while((len=fis.read(buf))!=-1) {
			System.out.println(new String(buf,0,len));
		}
		fis.close();
		*/
		
		System.out.println("-----------读的第三种方法----------");
		// TODO Auto-generated method stub
		FileInputStream fis=new FileInputStream("fos.txt");
 
		int len1=fis.available();//返回字节数
		System.out.println(len1);
		byte[] buf1=new byte[len1];//定义一个刚刚好的缓冲区,因为已经知道长度了,无需循环
	    fis.read(buf1);
	    fis.close();
	    //将所有的数据存入数组
	    //read(byte[]):从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 
	    //这个方法完成了两件事情:1:将字符字节流中的数据放入字符数组中2:返回存入的字节长度
	     System.out.println(new String(buf1));		

涉及到利用byte[]构建String

String(byte[] bytes)
String(byte[] bytes,  int offset, int length) //offset:第一个 byte 的索引         

二、write

1.方法

在这里插入图片描述

/*
Flushes this output stream and forces any buffered output bytes
to be written out. 
*/
void flush()

2.实例

FileOutputStream fos=new FileOutputStream("fos.txt");
		
fos.write("abcde".getBytes());//不用刷新,write是直接写入文件
		
fos.close();//虽然不刷新,但是得关资源

三、BufferedOutputStream

BufferedOutputStream在Java Program和Data Sink添加个buffer[]、BufferedInputStream是在Data Source和Java Program添加个buffer[]。原理类似,这里对BufferedOutputStream源码分析,加深对buffer理解。

1. 构造方法

   
    //The internal buffer where data is stored.
    protected byte buf[];

    //The number of valid bytes in the buffer. 
    protected int count;

   
    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);//默认size是8192
    }

    /*
     @param   out    the underlying output stream.
     @param   size   the buffer size.
     
    */
    public BufferedOutputStream(OutputStream out, int size) {
        super(out);//FilterOutputStream(OutputStream out)
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

2. write

When you write data to a Java BufferedOutputStream the data is cached internally in a byte buffer until the byte buffer is full, at which time the whole buffer is written to the underlying OutputStream.
在这里插入图片描述

   //从父类FilterOutputStream继承过来的变量
   protected OutputStream out;
   
    /** Flush the internal buffer */
    private void flushBuffer() throws IOException {
        if (count > 0) {
            out.write(buf, 0, count);
            count = 0;
        }
    }

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

   
    public synchronized void write(byte b[], int off, int len) throws IOException {
    
        //①将buf刷入文件 ②将b直接刷入文件(避免多次刷入) 顺序不能颠倒,否则文件会出错
        if (len >= buf.length) {
            flushBuffer();
            out.write(b, off, len);
            return;
        }
        
        //buf.length>len>buf剩余空间
        if (len > buf.length - count) {
            flushBuffer();
        }
        
        /*arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
        源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到
        目标数组中的 destPos到destPos+length-1 位置。 
        */
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

    /*
      Flushes this buffered output stream. This forces any buffered
     output bytes to be written out to the underlying output stream.
     */
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();//若out是FileOutputStream,则会调用其父类OutputStream的flush()
                   //它是个空方法,并没有做任何事情。
    }
    
   /*从父类FilterOutputStream继承过来的 try-with-resource 会在try后,调用out的close方法
     这个方法执行两个操作①flush  ②out.close()
     若BufferedOutputStream对象调用了close,则无需输出流OutputStream再调用close
   */
   public void close() throws IOException {
         try (OutputStream ostream = out) {
            flush();//也就是说即使buf不满,在flushBuffer关闭时,也会将buf刷入流中
        }
    }

理解 try (OutputStream ostream = out):深入理解 Java try-with-resource 语法糖

flush()调用:
If you want to make sure that all written data is written to disk without having to close the BufferedOutputStream you can call its flush() method. Calling flush() will make sure that all data which has been written to the BufferedOutputStream so far, is fully written to the underlying OutputStream too, plus flush() will also have been called on the underlying OutputStream.
在没有close()时,将buff[]数据刷入流中。

3.测试

FileOutputStream fos=new FileOutputStream("C:\\Users\\ASUS\\Desktop\\tmp.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
bos.write(1);
bos.close();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章