Fork me on GitHub

Java IO 流

  1. IO 流主要用来处理设备之间的数据传输
  2. Java 对数据的操作主要通过流的方式
  3. Java 用于操作流的对象都在 IO 包中
  4. 流按操作数据的不同分为: 字节流和字符流
  5. 流按流向分为: 输入流和输出流
    • 将外部设备中的数据读取到内存中: 输入
    • 将内存中的数据写入到外部设备中: 输出

字符流

  • 字符流的由来:
    字节流读取文本字节数据后, 不直接操作而是先查指定的编码表, 获取对应的文字,
    然后再对文字进行操作, 简单说: 字符流 = 字节流 + 编码表.
  • 字符流的抽象基类(顶层父类): Reader, Writer
// 需求一: 将一些文字存储到硬盘的一个文件中

    /*
     * 思路:
     *    如果要操作文字数据, 建议优先考虑字符流.
     *    而且需要将数据从内存中写入到硬盘上, 要使用字符流中的输出流: Writer
     *    硬盘的数据基本体现是文件, 希望找到一个可以操作文件的 Writer
     *    通过查阅 API , 找到了操作文件的 FileWriter 子类
     *  注意: 该子类没有空参的构造函数.
     *  原因: 既然是往一个文件中写入文本数据, 那么创建对象时, 就必须明确存储数据的目的地
     *       (即构造函数中的参数为 File 对象或者为文件名)
     */

    // 创建一个可以往文件中写入字符数据的字符输出对象
    // 如果文件不存在, 则会自动创建
    // 如果文件存在, 则会覆盖
    // 如果构造函数中加入 true, 可以实现对文件进行续写. 否则, 是覆盖
    FileWriter fw = new FileWriter("demo.md", true);

    // 获取系统默认的行分隔符
    final String LINE_SEPARATOR = System.getProperty("line.separator");

    // 调用 Writer 对象的 write(string) 方法,写入数据
    // 其实数据写入到临时缓冲区中
    fw.write("abcd"+LINE_SEPARATOR+"hahaha");

    // 进行刷新, 将数据直接写入到目的地中
    fw.flush();

    // 关闭流, 关闭资源
    // 关闭之前, 默认会先调用 flush() 刷新缓冲区中的数据到目的地
    // 关闭之后, 在调用 write() 或 flush() 将导致抛出 IOException 异常
    fw.close();


// 需求二: 读取一个文本文件, 将读取到的字符打印到控制台
         //  FileReader 类

    public static void main(String[] args) throws IOException {

        // 创建读取字符数据的流对象
        // 在创建读取流对象时, 必须要明确被读取的文件, 一定要确定该文件是存在的

        // 即用一个读取流关联一个已存在文件
        FileReader fr = new FileReader("demo.md");

        // 第一种方式: 读取单个字符

        // 用 Reader 中的 read 方法读取单个字符
        // 返回值为字符对应的整数,范围在: 0 到 65535 之间. 如果已达到流的末尾, 返回 -1
        //  int ch = fr.read();

        int ch = 0;
        while((ch=fr.read()) != -1){
            System.out.println((char)ch);
        }

        // 方式二: 读取数组  
        //  int read(char[] buf), 返回的是读取的字符数
        // 读取之前,先创建字符数组
        // 数组的长度一般为 1024 的整数倍
         char[] buf = new char[3];

        // int num = fr.read(buf); // 将一次读取到的字符存储到数组中

         // System.out.println(new String(buf));  // 将本次读取到的数组变成字符串,打印

         int len = 0;

         while((len=fr.read()) != -1){
            System.out.println(new String(buf,0,len));
        }

        fr.close(); // 关闭流资源
    }

// 需求三: 将 C 盘的一个文本文件复制到 D 盘


    // 分析:
    //     读取 C 盘文件中的数据
    //     将这些数据写入到 D 盘中
    //     连读带写

    // 思路:
    //     1. 需要读取源
    //     2. 将读到的源数据写入到目的地
    //     3. 既然是操作文本数据, 使用字符流

    public class CopyTextTest{
        public static void main(String[] args) throws IOException {

            // 1, 读取一个已有的文本文件, 使用字符读取流和文件关联
            FileReader fr = new FileReader("demo.txt");

            // 2. 创建一个目的, 用于存储读到的数据
            FileWriter fw = new FileWriter("copytext_1.txt");

            // 3. 频繁的读写操作,  每次读取一个字符
            int ch = 0;
            while((ch=fr.read())!=-1){
                fw.write(ch);
            }

            // 4. 关闭流资源
            fw.close();
            fr.close();
        }
    }

    // 第二种复制方式:
    public class CopyTextTest_2 {

        private static final int BUFF_SIZE = 1024;

        public static void main(String[] args){

            FileReader fr = null;
            FileWriter fw = null;
            try{
                fr = new FileReader("demo.txt");
                fw = new FileWriter("copytext_2.txt");

                char[] ch = new char(BUFF_SIZE);

                int len=0;
                while((len=fr.read(ch)) != -1){
                    fw.write(ch,0,len);
                }
            } catch(IOException e){
                throw new RuntimeException("读写失败");
            } finally{
                if(fr != null)
                    try{
                        fr.close();
                    } catch(IOException e){
                        e.printStackTrace();
                    }
                if(fw != null)
                    try{
                        fw.close();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
            }
        }
    }



_参考资料_ - [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3124795/index_11.html#page=1) - [JDK 1.6 中文文档](http://tool.oschina.net/apidocs/apidoc?api=jdk-zh)
posted @ 2017-09-10 20:32  小a的软件思考  阅读(176)  评论(0编辑  收藏  举报