java——IO(二)

缓冲流

缓冲流概述

  • 缓冲流也称为高效流,或者高级流。之前学习的字节流可以称为原十六
  • 作用:缓冲流自带缓冲区,可以提高原始字节流,字符流读写数据的性能
    在这里插入图片描述
    在这里插入图片描述
    缓冲流的作用:缓冲流自带缓冲区,可以提高原始字节流、字符流读写数据的性能

字节缓冲流

字节缓冲流的优化原理:

  • 字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能比较好
  • 字节缓冲输出流自带了8KB缓冲池,数据就直接写到缓冲池中去,写数据性能极高了
public static void main(String[] args) {
    
    
        //不需要释放资源,小括号里面自动释放资源
        try (
                //1.创建1个字节与管道相通
                InputStream is=new FileInputStream("file-io-app//src//data.txt");
                //a.把原始的字节输入流包装成高级的缓冲字节输入流
                InputStream bis=new BufferedInputStream(is);
                //2.创建一个字节输出流管道与目标文件接通
                OutputStream os=new FileOutputStream("file-io-app//src//data1.txt");
                //b.把字节输出流管道包装成高级缓冲字节输出流管道
                OutputStream bos=new BufferedOutputStream(os);
                ){
    
    
            //3.定义一个字节数组转移数据
            byte[] buffer=new byte[1024];
            int len;//记录每个数据读取的字节数
            while((len=bis.read(buffer))!=-1){
    
    
                bos.write(buffer,0,len);
            }
            System.out.println("复制完了");

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

    }

字节缓冲流的性能分析

用复制视频来分析

public class ByteBufferTimeDemo {
    
    
    public static final String SRC_FILE="D:\\Download\\Java入门基础视频教程,java零基础自学首选黑马程序员Java入门教程(含Java项目和Java真题)_P172_05、线程同步、同步代码块、同步方法、同步锁_分段1.flv";
    public static final String DESC_FILE="D:\\code\\";//这里的文件名不要写死,会导致四部操作都复制到同一个文件中
    public static void main(String[] args) {
    
    
        //copy01();//使用低级字节流按照一个一个字节的形式复制文件:慢的让人简直无法忍受。淘汰
        copy02();//使用低级字节流按照一个一个字节数组的形式复制文件。比较慢,但是可以忍受
        copy03();//缓冲流一个一个字节复制
        copy04();//缓冲流一个一个字节数组赋值:飞快 简直不要太快(推荐)
    }


    /**
     * 使用低级的字符按照一个一个字节的形式复制文件
     */
    private static void copy01() {
    
    
        long statTime=System.currentTimeMillis();
        try (
                InputStream is=new FileInputStream(SRC_FILE);
                OutputStream os=new FileOutputStream(DESC_FILE+"copy01.flv");
        ){
    
    

            int c;
            while ((c=is.read())!=-1){
    
    
                os.write(c);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        long endTime=System.currentTimeMillis();
        System.out.println("使用低级的字符按照一个一个字节的形式复制文件"+(endTime-statTime)/1000.0+"s");
    }

    /**
     * 使用低级字节流按照一个一个字节数组的形式复制文件
     */

    private static void copy02() {
    
    
        long statTime=System.currentTimeMillis();
        try (
                InputStream is=new FileInputStream(SRC_FILE);
                OutputStream os=new FileOutputStream(DESC_FILE+"copy02.flv");
        ){
    
    

            byte[] buffer=new byte[1024];
            int len;//记录每次读取的字节数
            while ((len=is.read(buffer))!=-1){
    
    
                os.write(buffer,0,len);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        long endTime=System.currentTimeMillis();
        System.out.println("使用低级字节流按照一个一个字节数组的形式复制文件"+(endTime-statTime)/1000.0+"s");
    }

    /**
     * 缓冲流一个一个字节复制
     */

    private static void copy03() {
    
    
        long statTime=System.currentTimeMillis();
        try (
                //1.创建1个字节与管道相通
                InputStream is=new FileInputStream(SRC_FILE);
                //a.把原始的字节输入流包装成高级的缓冲字节输入流
                InputStream bis=new BufferedInputStream(is);
                //2.创建一个字节输出流管道与目标文件接通
                OutputStream os=new FileOutputStream(DESC_FILE+"copy03.flv");
                //b.把字节输出流管道包装成高级缓冲字节输出流管道
                OutputStream bos=new BufferedOutputStream(os);
        ){
    
    

            int c;
            while ((c=bis.read())!=-1){
    
    
                bos.write(c);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        long endTime=System.currentTimeMillis();
        System.out.println("使用缓冲的字符按照一个一个字节的形式复制文件"+(endTime-statTime)/1000.0+"s");
    }
    private static void copy04() {
    
    
        long statTime=System.currentTimeMillis();
        try (
                //1.创建1个字节与管道相通
                InputStream is=new FileInputStream(SRC_FILE);
                //a.把原始的字节输入流包装成高级的缓冲字节输入流
                InputStream bis=new BufferedInputStream(is);
                //2.创建一个字节输出流管道与目标文件接通
                OutputStream os=new FileOutputStream(DESC_FILE+"copy04.flv");
                //b.把字节输出流管道包装成高级缓冲字节输出流管道
                OutputStream bos=new BufferedOutputStream(os);
        ){
    
    

            byte[] buffer=new byte[1024];
            int len;//记录每次读取的字节数
            while ((len=bis.read(buffer))!=-1){
    
    
                bos.write(buffer,0,len);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        long endTime=System.currentTimeMillis();
        System.out.println("使用缓冲字节流按照一个一个字节数组的形式复制文件"+(endTime-statTime)/1000.0+"s");
    }
}

在这里插入图片描述
综上:建议使用字节缓冲输入流、字节缓冲输出流,结合数组的方式,目的前来看是性能最优的组合

字符缓冲流

字符缓冲输入流:BufferedReader
作用:提高字符输入流读取数据的性能,除此之外多了按照多了按照读取数据的功能

/**
 * 目标学会缓冲字符输入流提高字符输入流的性能,新增了按照读取的方法(经典代码)
 */
public class BufferedReaderDemo1 {
    
    
    public static void main(String[] args) {
    
    
        try (
                Reader fr=new FileReader("file-io-app\\src\\data.txt");
                BufferedReader br=new BufferedReader(fr);
                ){
    
    

//            char[] buffer=new char[1024];
//            int len;
//            while ((len=fr.read(buffer))!=-1){
    
    
//                String rs=new String(buffer,0,len);
//                System.out.println(rs);
//            }
            //如果空行下面没有行就都null
            String line;
            while ((line=br.readLine())!=null)
                System.out.println(line);

        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

字符缓冲输出流:BufferedWriter
作用:提高字符输出流写数据的性能,除此之外多了换行的功能

**
 * 目标:缓冲字符输出流的使用,学会他多出来一个功能,newLine()
 */
public class BufferedWriterDemo2 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.创建一个字符输出流管与目标文件接通
        Writer fw=new FileWriter("file-io-app\\src\\data.txt",true);
        //覆盖管道,每次启动都会清空文件之后的数据
        BufferedWriter bw=new BufferedWriter(fw);
        bw.write('a');
        bw.write('c');
        bw.newLine();//bw.write("\r\n");

        bw.write("adasda",0,5);
    }


}

案例
需求:把《出师表》的文章顺序进行回复发哦一个新文件中

转换流

字符输入转换流

之前使用字符流读取数据没有乱码,因为代码和文件编号都是UTF-8,但是如果代码便哈和文件编码不一致,使用字符流直接读取会乱码。
可以使用字符输入转换流解决这个问题。
可以提取文件BGK的原始字节流,原始字节不会存在问题
然后把字节流以指定编码转换成字符输入流,这样字符输入流中的字符就不会乱码了

    public static void main(String[] args) throws Exception {
    
    
        InputStream is=new FileInputStream("ss");
        //2.把原始字节流转换成字符输入流
        Reader isr=new InputStreamReader(is,"GBK");//就是这一句
        BufferedReader br=new BufferedReader(isr);
        String line;
        while ((line=br.readLine())!=null){
    
    
            System.out.println(line);
        }
    }

字符输出转换流

可以把字符以指定变化获取字节后再使用字节输出流写出去"我爱你中国.getBytes(编码)"。也可以使用字符输出转换流实现

序列化对象

对象序列化

作用:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化
使用到的流是对象字节输出流:ObjectOutPutStream(把低级字节输出流包装成高级的对象字节输出流)
在这里插入图片描述

/**
 * 目标:学会对象序列华,使用ObjecOutStream把内存中的都西昂存入到磁盘文件中
 * 对象如果一定要序列化,那就一定要实现一个接口
 */
public class ObjectOutputStreamDemo1 {
    
    

    public static void main(String[] args) throws IOException {
    
    
        //创建学生对象
        Student s=new Student("小米","chenlei","123333",21);
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("file-io-app/src/data.txt"));
        //3.直接使用序列化法
        oos.writeObject(s);
        //4.释放资源
        oos.close();

    }
}

/**
 * 如果需要序列化,就一定要是实现Serializable接口
 */
public class Student implements Serializable {
    
    
    private String name;
    private String loginName;
    private String passWord;
    private int age;

    public Student() {
    
    
    }

    public Student(String name, String loginName, String passWord, int age) {
    
    
        this.name = name;
        this.loginName = loginName;
        this.passWord = passWord;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", loginName='" + loginName + '\'' +
                ", passWord='" + passWord + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getLoginName() {
    
    
        return loginName;
    }

    public void setLoginName(String loginName) {
    
    
        this.loginName = loginName;
    }

    public String getPassWord() {
    
    
        return passWord;
    }

    public void setPassWord(String passWord) {
    
    
        this.passWord = passWord;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }
}

对象反序列化

对象反序列化使用到的流是对象字节输入流:ObjectInputStream
作用:以内存为基准,把存储到文件中去的对象数据恢复成内存中的对象,称为对象反序列化

public class ObjectInputStreamDemo {
    
    
    public static void main(String[] args) throws Exception {
    
    
        ObjectInputStream is=new ObjectInputStream(new FileInputStream("file-io-app/src/data.txt"));
        Student s=(Student) is.readObject();
        System.out.println(s);
    }
}
/**
 * 如果需要序列化,就一定要是实现Serializable接口
 */
public class Student implements Serializable {
    
    
    //申明徐磊画的版本好
    //序列化的版本好与反序列化的版本好必须一致猜不会出错!
    private static final long seriaVersionUID=1;
    private String name;
    private String loginName;
    private transient String passWord;//transient修饰的成员变量不参与序列化,返回的是null
    private int age;

打印流

作用:打印流可以实现方便、高校的打印数据到文件中去。打印流一般是指:PrintStream,PrintWriter两个类
可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true

  • PrintStream
    在这里插入图片描述
public class PrintDemo1 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //PrintStream ps=new PrintStream("file-io-app/src/data.txt");//之前的数据会被清空
        PrintStream ps=new PrintStream(new FileOutputStream("file-io-app/src/data.txt",true));//这样才是最佳数据
        
        ps.println(97);
        ps.println('a');
        ps.println(true);
        ps.println("我是答应输出流的,我是啥就打印啥");
        ps.close();
    }
}
  1. 打印流有几种?各有什么特点
    - 打印流一般指:PrintStream,PrintWrite两个类
    - 打印功能2者是一样的使用方式
    - PrintStream继承自字节输出流OutputStream,支持写字节
    - PrintWrite继承自字节输出流Writer,支持写字符
  2. 打印的优势是什么
    - 两者在打印功能都是使用方便,性能高校(核心优势)
public static void main(String[] args) throws Exception {
    
    
        System.out.println("拆迁办一个");
        System.out.println("发生发射点");
        //改变输出语句的位置
        PrintStream ps=new PrintStream("file-io-app/src/data.txt");
        System.setOut(ps);
        System.out.println("撒大啊大大是");
        System.out.println("士大夫首发式");
    }

补充知识:Properties

  • Properties属性级对象
    其实就是一个Map集合
    核心作用:代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去
    属性文件:后缀是.properties结尾的文件,里面的内容都是key=value,后续做系统配置信息
public class PropertiesDemo1 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Properties properties=new Properties();
        properties.setProperty("admin","1212");
        System.out.println(properties);
        properties.store(new FileWriter("file-io-app/src/data.txt"),"this is just a comments");
        
    }
}

补充知识:IO框架

在这里插入图片描述
在这里插入图片描述

    public static void main(String[] args) throws Exception {
    
    
        //1.完成文件复制
        IOUtils.copy(new FileInputStream("D:\\我的文件\\证书及成绩单\\蓝桥杯1.jpg"),new FileOutputStream("D:\\我的文件\\copy.jpg"));

        //完成文件复制到某个文件夹下
        FileUtils.copyFileToDirectory(new File("D:\\我的文件\\证书及成绩单\\蓝桥杯1.jpg"),new File("D:\\我的文件"));
        //完成某个文件夹复制到某个文件夹下,可以创建不存在的文件夹
        FileUtils.copyDirectoryToDirectory(new File("D:\\我的文件\\证书及成绩单"),new File("D:\\new"));
    }

猜你喜欢

转载自blog.csdn.net/weixin_46362658/article/details/123585081
今日推荐