zoukankan      html  css  js  c++  java
  • 初识字节流+实现缓冲字节流

    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

  • 相关阅读:
    UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)
    UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
    【Same Tree】cpp
    【Recover Binary Search Tree】cpp
    【Binary Tree Zigzag Level Order Traversal】cpp
    【Binary Tree Level Order Traversal II 】cpp
    【Binary Tree Level Order Traversal】cpp
    【Binary Tree Post order Traversal】cpp
    【Binary Tree Inorder Traversal】cpp
    【Binary Tree Preorder Traversal】cpp
  • 原文地址:https://www.cnblogs.com/wewill/p/5588761.html
Copyright © 2011-2022 走看看