达内课程-高级流/操作流BufferedOutputStream/BufferedInputStream

来源:互联网 发布:微博怎么设置个性域名 编辑:程序博客网 时间:2024/05/19 01:32

高级流/操作流

1、与其他流相接,提供特定数据处理功能
2、操作其他流的流

BufferedInputStream/BufferedOutputStream
1、提供内存缓冲区,提高单字节读写效率
2、BufferedOutputStream
输出的字节值,暂存在内存数组中,
放满后,自动批量输出
不满,flush()手动刷出
3、BufferedInputStream
读取一批字节值,暂存在内存数组中
可以一个字节一个字节的处理数组中的数据
这一批处理完,再缓存下一批

磁盘读取效率低,内存读取效率高

创建对象
1、BufferedOutputStream out = new BufferedOutputStream(相接的流);
内部缓存数组长度8192
2、BufferedOutputStream out = new BufferedOutputStream(相接的流,16*1024);
内部缓存数组长度16k

方法
write(int b)//末尾1个字节
write(byte[] buff)//全部指定的数组
write(byte[] buff,int from,int length)//从from开始的length个
flush()//刷出缓存数据

read();//读取一个字节
read(byte[] buff);//根据传入的数组长度读取
available();//获取剩余的可读取字节量

这些方法都是从父类继承的,没有特殊方法

栗子

FileOutputStream fos = new FileOutputStream("d:/abc/f4");        BufferedOutputStream bos = new BufferedOutputStream(fos);        //这些数据被写进内存中,并没有写进文件        bos.write(97);        bos.write(98);        bos.write(99);        //内存大小8192,并没有存满,所以需要手动刷出        bos.flush();//手动刷出,可以重复执行        /*         * close()方法会先执行flush()         * 然后再执行out.close()         *          * 会先刷出缓存         * 再关闭相接的流         *          */        bos.close();

输出结果

abc

使用范围
如果是单字节读取,可以接buffer
对批量读取,效率并没有帮助

修改
达内课程-FileInputStream/FileOutputStream
的单字节读取

public class Test {    public static void main(String[] args) throws Exception {//选择父类型        System.out.println("请输入文件路径");        String s = new Scanner(System.in).nextLine();        File from = new File(s);        if(!from.isFile()){            System.out.println("请输入正确的文件路径");            return;        }        System.out.println("请输入目标文件路径");        String s2 = new Scanner(System.in).nextLine();        File to = new File(s2);        if(to.isDirectory()){            System.out.println("不是目录路径,是目标文件路径");            return;        }        try{            copy(from,to);            System.out.println("复制成功");        }catch(Exception e){            System.out.println("复制失败");            e.printStackTrace();        }    }    private static void copy(File from, File to) throws IOException {        // TODO Auto-generated method stub        BufferedInputStream in = new BufferedInputStream(new FileInputStream(from));        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(to));        int b;        while((b=in.read())!=-1){            out.write(b);        }        in.close();        out.close();    }}

练习:文件拆分/合并
将文件d:/abc/a.jpg拆分

拆分后的文件保存到d:/abc/a.jpg_aplit文件夹中
拆分后的文件名称为a.jpg.1
a.jpg.2
a.jpg.3

public class Test {    public static void main(String[] args) {        System.out.println("原文件路径");        String s = new Scanner(System.in).nextLine();        File file = new File(s);        if(!file.isFile()){            System.out.println("请输入正确的文件路径");            return;        }        System.out.println("拆分文件大小(kb)");        long size = new Scanner(System.in).nextLong();        size *= 1024;        try{            split(file,size);            System.out.println("拆分完成");        }catch(Exception e){            System.out.println("拆分失败");            e.printStackTrace();        }    }    private static void split(File file, long size) throws Exception {        //原文件名        String name = file.getName();        //准备拆分文件存放目录        File dir = new File(file.getAbsolutePath()+"_split");        if(dir.exists()){            //存在,清空            File[] files = dir.listFiles();            for(File file2:files){                file2.delete();            }        }else{            //不存在,新建            dir.mkdirs();        }        //字节计数变量  和  文件计数变量        long byteCount = 0;        int fileCount = 0;        FileInputStream in = new FileInputStream(file);        FileOutputStream out = null;        int b;        while((b=in.read())!=-1){            //如果没有输出流            //或者前一个文件满了            //创建新的输出流            if(out == null||byteCount == size){                //如果前面文件满了,要先关闭前一个流                if(out!=null){                    out.close();                }                out = new FileOutputStream(new File(dir,name+"."+(++fileCount)));                byteCount = 0;            }            out.write(b);            byteCount++;        }        in.close();        out.close();    }}

现有一个88k的图片

这里写图片描述

输出结果

原文件路径d:/abc/headimg.jpg拆分文件大小(kb)22拆分完成

这里写图片描述

这里写图片描述

仍然是单字节读取,增加效率如下

private static void split(File file, long size) throws Exception {        //原文件名        String name = file.getName();        //准备拆分文件存放目录        File dir = new File(file.getAbsolutePath()+"_split");        if(dir.exists()){            //存在,清空            File[] files = dir.listFiles();            for(File file2:files){                file2.delete();            }        }else{            //不存在,新建            dir.mkdirs();        }        //字节计数变量  和  文件计数变量        long byteCount = 0;        int fileCount = 0;        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));        BufferedOutputStream out = null;        int b;        while((b=in.read())!=-1){            //如果没有输出流            //或者前一个文件满了            //创建新的输出流            if(out == null||byteCount == size){                //如果前面文件满了,要先关闭前一个流                if(out!=null){                    out.close();                }                out = new BufferedOutputStream(new FileOutputStream(new File(dir,name+"."+(++fileCount))));                byteCount = 0;            }            out.write(b);            byteCount++;        }        in.close();        out.close();    }

单字节读写效率低时,可以选用Buffer

文件合并

public class Test {    public static void main(String[] args) throws Exception {        System.out.println("输入拆分文件存放的文件夹路径");        String s = new Scanner(System.in).nextLine();        File dir = new File(s);        if(!dir.isDirectory()){            System.out.println("请输入正确的文件夹路径");            return;        }        System.out.println("输入合并的目标文件名");        String s2 = new Scanner(System.in).nextLine();        File name = new File(s2);        if(name.isDirectory()){            System.out.println("请输入具体的文件路径,不是目录路径");            return;        }        try{            conbine(dir,name);            System.out.println("合并完成");        }catch(Exception e){            System.out.println("合并失败");            e.printStackTrace();        }    }    private static void conbine(File dir,File name) throws Exception {        File[] list = dir.listFiles(new FileFilter(){            @Override            public boolean accept(File f) {                //只列出数字后缀的文件                if(f.isDirectory()){return false;}                String n = f.getName();                int index = n.lastIndexOf(".");                if(index == -1){return false;}                n = n.substring(index+1);                return n.matches("\\d+");            }        });        //外接比较器,对文件按数字大小排序        Arrays.sort(list,new Comparator<File>(){            @Override            public int compare(File f1, File f2) {                String n1 = f1.getName();                String n2 = f2.getName();                n1 = n1.substring(n1.lastIndexOf(".")+1);                n2 = n2.substring(n2.lastIndexOf(".")+1);                int a = Integer.parseInt(n1);                int b = Integer.parseInt(n2);                return a - b;            }        });        FileOutputStream out = new FileOutputStream(name);        FileInputStream in = null;        byte[] buff = new byte[8192];        int n;        for(File f:list){            in = new FileInputStream(f);            while((n=in.read(buff))!=-1){                out.write(buff,0,n);            }            in.close();        }        out.close();    }}

输出结果

输入拆分文件存放的文件夹路径d:/abc/headimg.jpg_split输入合并的目标文件名d:/abc/copy.jpg合并完成
阅读全文
0 0
原创粉丝点击