JavaSE学习---I/O流学习分享

I/O流概述:

i:Input,以内存为基准,表示从硬盘中读取数据到内存中。

o: Outerput,以内存为基准,表示将内存中的数据写到硬盘中。

 

I/O流体系

 

 

 原始流


 1、原始字节流

  • FileInputStream: (文件字节输入流)

 

作用:将文件中的字节读取到内存中来。

public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt"); //定位文件路径
        InputStream is = new FileInputStream(f);  //以多态形式 创建了一个文件字节输入流管道
        int data = is.read();   //读取is管道中的一个字节, 返回结果为ASCII编码的数值形式
        System.out.println((char) data);  //结果:a

        int data2 = is.read();  //继续读取is管道中的第二个字节
        System.out.println((char) data2);  //结果:b

        int data3 = is.read(); //文件读取完毕后将返回-1
        System.out.println(data3);   //结果:-1
        
        is.close();  //关闭管道
    }
}

上述代码简单易懂,但读取效率低下。因为在读取管道字节时是一个字节一个字节读取的,我们可以想法一次多读几个字节,减少读取次数,从而提高读取效率。

public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt");  //文件内容:abc123ab
        InputStream is = new FileInputStream(f);

        byte[] buffer = new byte[3]; //定义一个字节数组,每次在管道中读取3个字节
        is.read(buffer); //buffer数组相当于一个水桶,每次在is管道中接3个字节
        String data = new String(buffer); //将字节数组解码为字符串。
        System.out.println(data);  //结果:abc

        is.read(buffer);
        String data2 = new String(buffer);
        System.out.println(data2); //结果:123

        is.read(buffer);
        String data3 = new String(buffer);
        System.out.println(data3);  //结果:ab3 //预期结果应该为ab才对呀。原因是最后一桶水没有装满,3是残留的上一桶的
        /*
        解决方案:
                在is.read(buffer)读取管道字节时,会返回读取的字节个数,
                可以在解码字节数组时,指定长度(接多少读多少)
        int len;
        while ((len = is.read(buffer))!= -1) {
            String data = new String(buffer, 0, len);  //接多少读多少
            System.out.println(data);
        }
         */
        is.close(); //在不用此管道时须关闭管道,否则会影响cpu性能
    }
}
  • FileOutputStream:(文件字节输出流)

作用:将内存中的字节写入到硬盘文件中去。

public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt");  //定位要写入到的文件路径,没有则自动创建
        OutputStream os = new FileOutputStream(f); //创建文件字节输出流管道,连接内存与磁盘文件
        os.write('a'); //将一个字节a 利用os管道写入到文件中   //os.write(97); //效果相同

        byte[] data = {'a','b','c'};
        os.write(data);    //将字节数组写入到文件中

        byte[] data2 = "我爱迪迪".getBytes();  //将字符串转换成字节数组
        os.write(data2);

        //os.flush();  //写数据到文件最后一定要刷新,  因为写的速度比较慢,可能会有数据还在管道中
        os.close();  //关闭管道,会自动刷新管道。
    }
}

2、原始字符流

  • FileReader:(文件字符输入流)

作用:将文件中的的字符读取到内存中来

public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt");  //定位文件路径 ab爱
        Reader rs = new FileReader(f);  //以多态形式,创建一个字符输入流管道

        int data = rs.read();  //从字符输入流管道中读取一个字符 以ASCII码数值形式返回
        System.out.println((char) data); //a

        int data2 = rs.read();  
        System.out.println((char) data2); //b

        int data3 = rs.read();  
        System.out.println((char) data3); //爱  //用字符输入流读取中文不存在乱码现象

        int data4 = rs.read();
        System.out.println(data4);  //-1  //读取完毕返回-1

    }
}

与字节输入流类似。上述代码只能从字符输入流中一次读取一个字符,可以用一个字符数组一次读取多个字符,提高读取效率。

public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt"); //ab爱123a
        Reader rs = new FileReader(f);
        char[] buffer = new char[3]; //定义一个字符数组,相当于一个水桶每次在字符输入流中提取3个字符
        
        rs.read(buffer);  //拿着buffer去读取字符,每次读取3个字符
        System.out.println(buffer); //ab爱

        rs.read(buffer);
        System.out.println(buffer); //123

        rs.read(buffer);
        System.out.println(buffer); //a23   //预期应为a,原因是因为残留的上一次的
        /*
        解决方案:
            int len;
            while ((len = rs.read(buffer)) != -1) {
                String data = new String(buffer, 0, len); //接多少读取多少
                System.out.println(data);
        }
         */
    }
}
  • FileWrite:(文件字符输出流)

作用:将文件中的字符写入到文件中去。

public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt"); //定位文件
        Writer wr = new FileWriter(f); //定义一个文件字符输出流文件

        wr.write(97); //写字符a到文件 
        wr.write('a'); //写字符a到文件 
        wr.write("我爱迪迪");   //也可直接写字符串到文件

        //wr.flush();  //刷新管道, 写数据到文件一定要刷新。
        wr.close(); //关闭管道 会默认刷新管道
    }
}

 

 

高级流


一、缓冲流

概述:缓冲流自带缓冲区可以提高原始流的读写效率。cpu处理磁盘文件比较慢,而利用缓冲区就不需要直接对磁盘进行操作,仅对缓冲区进行操作,从而提高读写效率。

1.字节缓冲流

  • BufferedInputStream: (缓冲字节输入流)
public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt"); //定位文件
        InputStream is = new FileInputStream(f); //创建普通文件字节输入流
        InputStream bis = new BufferedInputStream(is); //将文件字节输入流包装成 缓冲字节输入流. 此时可以像操作低级流一样操作bis.

        byte[] buffer = new byte[3];
        int len;
        while ((len = bis.read(buffer)) != -1) {
            System.out.print(new String(buffer,0, len));  //每桶接多少读多少
        }
    }
}
  • BufferedOutputStream: (缓冲字节输出流)
public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt"); //定位文件
        OutputStream os = new FileOutputStream(f); //创建普通字节输出流
        OutputStream bos = new BufferedOutputStream(os); //将普通字节输出流 包装成 缓冲字节输出流,此时可以像操作普通字节输出流一样操作bos

        bos.write(97); //写一个字节a到文件

        bos.write('a'); //写一个字节a到文件

        byte[] data = {'a','b','c'}; //写一个字节数组到文件
        bos.write(data);

        byte[] data2 = "我爱你".getBytes();  // getBytes(): 将字符串转换成字节数组
        bos.write(data2); //写一个字节数组到文件


        bos.close();
    }
}

 2、字符缓冲流 

  • BufferedReader: (缓冲字符输入流)
public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt"); //定位文件
        Reader rs = new FileReader(f); //普通文件字符输入流
        BufferedReader brs = new BufferedReader(rs); //将普通文件字符输入流 包装成 缓冲字符输入流。 此时缓冲流brs可以像普通字符输入流一样操作
        
        String info;
        while ((info = brs.readLine()) != null) { //字符缓冲输入流新增功能 readLine():读取一行
            System.out.println(info);
        }
    }
}
  • BufferedWriter: (缓冲字符输出流)
public class Demo {
    public static void main(String[] args) throws Exception {
        File f = new File("javase/src/code/word.txt"); //定位文件
        Writer w = new FileWriter(f,true); //定义普通文件字符输出流 //在低级文件输出流中加true可追加文件
        Writer bw = new BufferedWriter(w); //将文件字符输出流 包装成 缓冲字符输出流,

        bw.write('a'); 
        bw.write("我爱你");
        
        bw.close();
    }
}

缓冲流总结缓冲流并不复杂,仅仅是在普通文件流的基础上加了一层包装,用于提高文件读写的效率。 

 

二、打印流

作用:可以方便、高效的将内存中的数据打印到文件中去。打印什么就是什么,例如将97打印到文件中就是97,而不是a。

1、PrintStream

public class Demo {
    public static void main(String[] args) throws Exception {
        /*
            创建打印流对象:
                方式一: new PrintStream(文件对象)
                方式二: new PrintStream("文件路径")
                方式三: new PrintStream(字节输出流对象) 
         */

        //方式一
        File f = new File("javase/src/code/word.txt");
        PrintStream ps = new PrintStream(f);
        ps.println(97); //97
        ps.println('a'); //a
        ps.println("我爱迪迪"); //我爱迪迪

        //方式二
        PrintStream ps2 = new PrintStream("javase/src/code/word.txt");
        ps2.println(97); //97
        ps2.println('a'); //a
        ps2.println("我爱迪迪"); //我爱迪迪

        //方式三
        OutputStream os = new FileOutputStream("javase/src/code/word.txt",true); //添加true参数可以追加文件数据,而非覆盖
        PrintStream ps3 = new PrintStream(os);
        ps3.println(97); //97
        ps3.println('a'); //a
        ps3.println("我爱迪迪"); //我爱迪迪
    }
}

2、PrintWriter

public class Demo {
    public static void main(String[] args) throws Exception {
        /*
            创建打印流对象:
                方式一: new PrintWriter(文件对象)
                方式二: new PrintWriter("文件路径")
                方式三: new PrintWriter(字节输出流对象)
                方式四: new PrintWriter(字符输出流对象)
         */
        //方式一:
        File f = new File("javase/src/code/word.txt");
        PrintWriter pw = new PrintWriter(f);
        pw.println(97); //97                //pw.write(97);
        pw.println('a');  //a               //pw.write('a');
        pw.println("我爱迪迪"); //我爱迪迪     //pw.write("我爱迪迪");
        pw.close(); //关闭打印流

        //方式二:
        PrintWriter pw2 = new PrintWriter("javase/src/code/word.txt");
        pw2.println(97); //97                //pw2.write(97);
        pw2.println('a');  //a               //pw2.write('a');
        pw2.println("我爱迪迪2"); //我爱迪迪     //pw2.write("我爱迪迪2");
        pw2.close(); //关闭打印流

        //方式三:
        PrintWriter pw3 = new PrintWriter(new FileOutputStream("javase/src/code/word.txt",true));
        pw3.println(97); //97                //pw3.write(97);
        pw3.println('a');  //a               //pw3.write('a');
        pw3.println("我爱迪迪3"); //我爱迪迪     //pw3.write("我爱迪迪3");
        pw3.close(); //关闭打印流

        //方式四
        PrintWriter pw4 = new PrintWriter(new FileWriter("javase/src/code/word.txt",true));
        pw4.println(97); //97                //pw4.write(97);
        pw4.println('a');  //a               //pw4.write('a');
        pw4.println("我爱迪迪4"); //我爱迪迪     //pw4.write("我爱迪迪4");
        pw4.close(); //关闭打印流
    }
}

总结:PrintStream与PrintWriter差比很小,几乎可以混用,一般使用PrintStream就可以。

 

三、转换流

  • InputStreamReader:(字符转换输入流)

作用:将文件以某种指定的字符格式读取。

public class Demo {
    public static void main(String[] args) throws Exception {
        /*
            转换步骤:
                1.获取数据的文件字节输入流
                2.将得到的文件字节输入流转换为指定格式的字符流
         */
        InputStream is = new FileInputStream("D:/桌面/word2.txt"); //原始字节输入流   word2.txt为GBK形式
        Reader isr = new InputStreamReader(is, "GBK");  //将原始字节输入流,以指定的GBK编码形式转换成字符输入流。

        BufferedReader br = new BufferedReader(isr);
        String info;
        while ((info = br.readLine()) != null) {
            System.out.println(info);
        }
    }
}
  • OutputStreamReader:(字符转换输出流)

作用:将内存中的数据以指定格式写入磁盘文件。

public class Demo {
    public static void main(String[] args) throws Exception {
        /*
            转换步骤:
                1.获取原始字节输出流
                2.将得到的原始字节输出流转换成指定格式的字符输出流
         */
        OutputStream os = new FileOutputStream("D:/桌面/word2.txt");
        Writer w = new OutputStreamWriter(os, "GBK");  //创建以GBK格式的输出管道
        
        w.write("我爱你");
        w.close();
    }
}

 四、对象序列化

对象字节输出流ObjectOutputStream 

 概念:将内存中的对象储存到磁盘文件中去。

public class Demo {
    public static void main(String[] args) throws Exception {
        OutputStream os = new FileOutputStream("javase/src/code/word.txt");  //原始文件字节输出流
        ObjectOutputStream oos = new ObjectOutputStream(os);  //将原始文件字节输出流包装成对象输出流

        Student s1 = new Student("王小二", 21);  //注意:student此类必须实现Serializable接口
        oos.writeObject(s1);   //将对象储存到文件中

        oos.close();
    }
}

五、对象反序列化

对象字节输入流:ObjectInputStream

概念:将磁盘文件中的对象恢复到内存中来。 

public class Demo {
    public static void main(String[] args) throws Exception {
        InputStream os = new FileInputStream("javase/src/code/word.txt");  //创建原始字节输入流
        ObjectInputStream ois = new ObjectInputStream(os);  //将原始字节输入流包装成 对象输入流
        Student s = (Student) ois.readObject();  //对象反序列化

        System.out.println(s);

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值