• 初识字节流+实现缓冲字节流


    java中的IO流可以分为两种:字符流和字节流
    字符流,顾名思义,就是对字符进行操作,只能操作文本文件
    字节流,就是对字节进行操作,然而所有文件都是由字节组成的,可以字节流可以操作一切文件
    字符流中的两个大类:Reader和Writer
    详情可见 http://blog.csdn.net/noble510520/article/details/50083555 简单的Writer和Reader
    字节流中也同样有两个大类:InputStream和OutputStream
    又“读进来,写出去”,所以InputStream对应着Reader,OutputStream对应着Writer
    字节流和字符流有很多相像的地方,区别就是字节流操作字节,字符流操作字符


    OutputStream

    OutputStream的主要方法

    构造方法

    以FileOutputStream为例
    FileOutputStream(String file)
    FileOutputStream(File file)
    FileOutputStream(String file,boolean append)
    FileOutputStream(File file,boolean appeand)
    后面两种方法用于判断是否需要续写,前面两个方法是直接覆盖文件

    write(int charnum)
    write(byte[] array)
    write(byet[] array,int off,int len)写出array中角标从off开始的len个元素

    刷新

    flush()
    close()


    InputStream

    构造方法

    照惯例,以FileInputStream为例
    FileInputStream(String filename)
    FileInputStream(File filename)
    如果filename.exists==false||filename.isFile()==false的话,那么会抛出FileNotFoundException

    read():int
    read(byte[] array):int
    与Reader类一样,如果到了文件末尾,返回-1
    这里有个特别好用的方法,可以用来知道文件的大小
    available():int; 返回文件的字节数
    这时就可以用这个方法来定义array的大小,那么就可以一次性读完了

    关流

    flush()


    缓冲技术

    缓冲技术就是把信息分批处理,再一起丢出去,这样处理速度会快很多!!
    下面实现一下缓冲技术

    实现BufferedInputStream

    package mypackage;
    import java.util.*;
    import java.io.*;
    public class MyBufferedInputStream {
        private InputStream input;
        private int index=0;
        private byte[] array;
        private int len=0;  
        //默认分配一个100b的缓冲空间
        public MyBufferedInputStream(FileInputStream input){this(input,1024*100);}
        public MyBufferedInputStream(FileInputStream input,int size){
            this.input=input;
            array=new byte[size];
            }
        public int read()throws IOException{
            if(len==0){
                index=0;
                if((len=input.read(array))==-1){return -1;}
                }
            len--;
            return (array[index++]&255);//防止出现读到11111111此时错误的返回了-1
            }
        //重载read
        public int read(byte[] bytes)throws IOException{
            int i;
            int index=0;
            while((i=read())!=-1){
                bytes[index]=(byte)i;
                }
            return index+1;
            }
        public void close()throws IOException{input.close();}
        }

    实现BufferedOutputStream

    package mypackage;
    import java.util.*;
    import java.io.*;
    public class MyBufferedOutputStream{
        private OutputStream output;
        //默认分配一个100b的缓冲空间
        public MyBufferedOutputStream(FileOutputStream output)throws IOException{this(output,1024*100);}
        public MyBufferedOutputStream(FileOutputStream output,int size)throws IOException{
            this.output=output;
            buf=new byte[size];
            }
        //建一个输入,让写进来的数据先存在里面,最后再一起放出去
        protected byte[] buf;
        private int index=0;
            public void write(byte[] bytes)throws IOException{
                for(int i=0;i<bytes.length;){
                    buf[index++]=bytes[i++];
                    if(index==buf.length){
                        index=0;
                        output.write(buf);
                        this.flush();
                        buf=new byte[buf.length];
                        }
                    }
                }
        //重载write
        public void write(int bytes)throws IOException{
            if(index<buf.length){buf[index++]=(byte)bytes;}
            else{
                output.write(buf);
                output.flush();
                buf=new byte[buf.length];
                index=0;
                buf[index++]=(byte)bytes;
                    }
                }
        public void close()throws IOException{output.flush();output.close();}
        public void flush()throws IOException{output.flush();}
        }

    下面复制一个11.1M的MP3格式测试一下效果

    import java.io.*;
    import mypackage.*;
    class Test{
        public static void main(String[] agrs)throws IOException{
            long begin=System.currentTimeMillis();
            FileInputStream fi=new FileInputStream("D:\CloudMusic\薛之谦 - 一半.mp3");
            FileOutputStream fo=new FileOutputStream("D:\CloudMusic\一半1.mp3");
            MyBufferedInputStream bi=new MyBufferedInputStream(fi);
            MyBufferedOutputStream bo=new MyBufferedOutputStream(fo);
            int bytes;
            byte[] array=new byte[1024*100];
            while((bytes=fi.read(array))!=-1){
                bo.write(array);
                }
            bo.close();
            bi.close();
            long end=System.currentTimeMillis();
            System.out.println("复制所用时间:"+(end-begin)+"毫秒");
            }
        }

    下面是结果

    C:Users绍威Desktop>java Test
    复制所用时间:183毫秒

    用Java自带的BufferedInputStream和BufferedOutputStream试试

    import java.io.*;
    class Demo{
        public static void main(String[] args)throws IOException{
            long begin=System.currentTimeMillis();
            FileInputStream fi=new FileInputStream("D:\CloudMusic\薛之谦 - 一半.mp3");
            FileOutputStream fo=new FileOutputStream("D:\CloudMusic\一半1.mp3");
            BufferedInputStream bi=new BufferedInputStream(fi);
            BufferedOutputStream bo=new BufferedOutputStream(fo);
            byte[] a=new byte[1024*8];
            for(int i;(i=bi.read(a))!=-1;){
                bo.write(a);
                }
    
            bo.close();
            bi.close();
            long end=System.currentTimeMillis();
            System.out.println("复制所用时间:"+(end-begin)+"毫秒");
            }
        }

    下面是结果

    C:Users绍威Desktop>java Demo
    复制所用时间:117毫秒

    Tips:用write(byte[])会比write(int)快得多多
    输入的缓冲就是先把数据存在数组中,从数组中一个个读到控制台
    输出的缓冲就是把数据存到数组中,再一起写到OutputStream中的缓冲区,最后在刷新

    刚刚用这个复制一个11.1M的MP3花了0.6秒,和系统的时间差不多↖(^ω^)↗!!


    错误的返回了-1

    如果扫描到了11111111那么此时将byte->int是-1,如果这样的话,程序就会终止不会进行

    为什么read()返回的是Int型而不是byte型呢??

    1int=4byte
    那么11111111转为Int就是11111111 11111111 11111111 11111111 还是等于-1
    所以为了防止出现这个情况,就只保留后面八位,前面用0去补
    于是乎11111111&255

  • 相关阅读:
    linux
    linux
    linux
    linux
    linux
    linux
    linux
    idea插件篇之java内存分析工具(JProfiler)
    Jmeter(线程组+http请求+汇总报告)
    ZK客户端zkClient.bat
  • 原文地址:https://www.cnblogs.com/wewill/p/5588761.html
Copyright © 2020-2023  润新知