java io流 学习笔记

PS:大部分来源于参考资料的原话,总结的很好我就没改。

1. IO 流能干什么

通过IO我们能对硬盘文件进行读和写。(网络数据的传输也涉及到io)。

2. IO流的分类


按照 流的方向 进行分类:分为输入、输出流。

往内存中去:叫做输入(Input)。或者叫做读(Read)
从内存中出来:叫做输出(Output)。或者叫做写(Write)


按照 读取数据方式 不同进行分类:
按照 字节 的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
这种流是万能的什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件 等…

按照 字符 的方式读取数据的,一次读取一个字符.
这种流是为了方便读取 普通文本文件 而存在的,这种流不能读取:图片、声音、视频等文件。只能读取 纯文本文件,连word文件都无法读取。

注意:
纯文本文件,不单单是.txt文件,还包括 .java、.ini、.py 。总之只要 能用记事本打开 的文件都是普通文本文件。

3.IO流的顶层父类

    - 字节输入流:顶层父类:InputStream --> 抽象类   常见子类:FileInputStream
    - 字节输出流:顶层父类:OutputStream --> 抽象类   常见子类:FileOutputStream
    - 字符输入流:顶层父类:Reader --> 抽象类   常见子类:FileReader
    - 字符输出流:顶层父类:Writer --> 抽象类   常见子类:FileWriter

4.Java要掌握的流(16个)

1.文件专属:

  • java.io.FileInputStream(掌握)
  • java.io.FileOutputStream(掌握)
  • java.io.FileReader
  • java.io.FileWriter

2.转换流:(将字节流转换成字符流)

  • java.io.InputStreamReader
  • java.io.OutputStreamWriter

3.缓冲流专属:

  • java.io.BufferedReader
  • java.io.BufferedWriter
  • java.io.BufferedInputStream
  • java.io.BufferedOutputStream

4.数据流专属:

  • java.io.DataInputStream
  • java.io.DataOutputStream

5.标准输出流:

  • java.io.PrintWriter
  • java.io.PrintStream(掌握)

6.对象专属流:

  • java.io.ObjectInputStream(掌握)
  • java.io.ObjectOutputStream(掌握)

7.File文件类

  • java.io.File

5.输入流

PS: 下面很多try,catch 捕获异常,都不是我写的,当然第一次写的话,可以自己敲一下,但是alt + z 直接快捷生成。

另外,就是那几个常用的方法(我自己觉得),其实会写前几个,其实剩余都比较好记住。

我的conf.txt文件和src在同一个目录。

FileInputStream

public class IODemo1 {
    public static void main(String[] args)  {
        File file = new File("conf.txt");
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);

            byte[] bytes = new byte[3]; // 做缓存用的,一次最多4个字节
            int redCount = 0;

            // inputStream去读取,而每次读取到的字节文件存放到bytes中。
            while ((redCount = inputStream.read(bytes)) != -1){ // read读取值是字节数量,读取不到返回-1
                System.out.println("转换后的字符:"+new String(bytes, "UTF-8"));
                System.out.println("读取字节数量:"+redCount);
                System.out.println("----------------");
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 失败与否都要关闭io
            if(inputStream != null){ // 判断文件是否为null
                try{
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

InputStreamReader

就是有这么一种写法。

将字节输入流转换字符输入流。

public class IODemo {
    public static void main(String[] args)  {
        File file = new File("conf.txt");
        FileInputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        try {
             inputStream = new FileInputStream(file);
             inputStreamReader = new InputStreamReader(inputStream,"UTF-8"); // 转换为为字符输入流

            byte[] bytes = new byte[3]; // 做缓存用的,一次最多4个字节
            char[] chars = new char[1];
            int redCount = 0;

            // inputStream去读取,每次读取到字节存放到bytes中。
            //while ((redCount = inputStream.read(bytes)) != -1){ // read读取值是字节数量,读取不到返回-1
            //    System.out.println("转换后的字符:"+new String(bytes, "GBK"));
            //    System.out.println("读取字节数量:"+redCount);
            //}
            System.out.println("---------------");
            // 对一个文件不能同时开2个输入流
            while ((redCount = inputStreamReader.read(chars)) != -1){
                System.out.println("读取字符数量:"+redCount);
                for (char aChar : chars) { // 遍历缓冲字符数组
                    System.out.println(aChar);
                }
                System.out.println("将字符数组转换成字符串:"+ new String(chars));
                System.out.println("---------------");
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 失败与否都要关闭io
            if(inputStreamReader != null){
                try{ // 流的关闭要区分顺序,先关闭外层也就是包装那一层
                    inputStreamReader.close();
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

FileReader

文件字符读取的形式

public class FileReaderDemo {
    public static void main(String[] args) {
        File file = new File("conf.txt");
        FileReader fileReader = null;
        try {
            char[] chars = new char[4];
            int readCount = 0;
            fileReader = new FileReader(file);
            while ((readCount = fileReader.read(chars)) != -1){
                System.out.println(new String(chars));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileReader != null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

BufferedReader

自带缓存的字符输入流。构造参数是一个字符输入流。

public class BufferReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("conf.txt");
        // 当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
        // 外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流。
        // 像当前这个程序来说:FileReader就是一个节点流。BufferedReader就是包装流/处理流。
        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String str = null;
        while ((str = bufferedReader.readLine()) != null){ // readLine()方法读取一个文本行,但不带换行符。
            System.out.println(str);
        }

        bufferedReader.close(); // 关闭最外层即可
    }
}

ObjectInputStream

反序列化对象

        // 反序列化
        ObjectInputStream oin = new ObjectInputStream(new FileInputStream("conf1.txt"));
        Object o = oin.readObject();
        System.out.println(o);

6.输出流

FileOutputStream


public class IoDemo2 {
    public static void main(String[] args) {
        File file = new File("conf.txt");
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file,true); // 开启文件追加模式
            String wls = "万乐姝";
            byte[] bytes = wls.getBytes(StandardCharsets.UTF_8); // 将string转换为字节文件
            outputStream.write(bytes); // 写入
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(outputStream != null){
                try {
                    outputStream.flush(); // 先刷新在关闭,否则可能有bug
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

OutputStreamWriter

public class IoDemo2 {
    public static void main(String[] args) {
        File file = new File("conf.txt");
        FileOutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        try {
            outputStream = new FileOutputStream(file,true); // 开启文件追加模式
            outputStreamWriter = new OutputStreamWriter(outputStream);
            outputStreamWriter.write("万乐姝");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(outputStream != null){
                try {
                    outputStreamWriter.flush(); // 先关闭外层流
                    outputStreamWriter.close();
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

FileWriter

public class FileWriterDemo {
    public static void main(String[] args) {
        File file = new File("conf.txt");
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(file,true); // 开启文件追加模式
            fileWriter.write("卧槽");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileWriter.flush();
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

BufferedWriter

public class BufferWriterDemo {
    public static void main(String[] args) throws IOException {
        FileWriter fileWriter = new FileWriter("conf.txt",true);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        bufferedWriter.write("qhxxxx");
        bufferedWriter.close();

    }
}

PrintStream

 我们平时用的控制台打印语句就是PrintStream对象

改变流的输出方向

System.setOut(PrintStream对象)

 PrintStream printStream = new PrintStream(new FileOutputStream("conf.txt"));
        printStream.println("\n121212"); // 输出到conf.txt
        System.setOut(printStream); // 改变流的输出方向

        System.out.println("\n完了数"); // 输出到conf.txt了
        System.out.println("121212");

ObjectOutputStream

对新手感觉用处不大

要被序列化的对象必须实现  Serializable 接口

       // 序列化
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new             
        FileOutputStream("conf1.txt"));
        objectOutputStream.writeObject(new User("qhx","1232323"));
        objectOutputStream.flush();
        objectOutputStream.close();

7.配置properties文件的读取和设置

  • getProperty ( String key): 用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。
  • load ( InputStream inStream): 从输入流中读取属性列表(键和元素对)。通过对指定的文件(比如说上面的 test.properties 文件)进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。
  • setProperty ( String key, String value) : 调用 Hashtable 的方法 put 。他通过调用基类的put方法来设置 键 - 值对。
  • store ( OutputStream out, String comments): 以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。与 load 方法相反,该方法将键 - 值对写入到指定的文件中去。
  • clear (): 清除所有装载的 键 - 值对。该方法在基类中提供。
     

配置文件读取

  private static String getKey(String key) {
        Properties properties = new Properties();
        File file = new File(FILE_NAME);
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file); // 配置文件
            properties.load(inputStream); // 将配置文件对应的key,value映射到properties的map中。
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(inputStream != null){  // 还是这样关比较好,万一报错就tm关不了
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(properties.getProperty(key));
    }

配置文件设置

    /**
     * 配置文件设置
     *
     * @param key
     * @param value
     * @return
     */
    public static boolean setPropertiesKey(String key,String value) {
        // 判断key是否有重复
        String key1 = getKey(key);
        if(key1 == null){
            return setKey(key,value); 
        }
        return false;
    }

    /**
     *  配置文件设置
     *
     * @param key
     * @param value
     * @return boolean
     */
    private static boolean setKey(String key, String value) {
        Properties properties = new Properties();
        File file = new File(FILE_NAME); // 其实有其他配置可以同意下yaml文件里面配置,然后这里面读取,好统一调配。
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(file,true);
            properties.setProperty(key, value); // 存进map里面
            properties.store(fileWriter,""); // 将map对应的键值对写进输出流。这个comments 最后写入的时候是个注释
        } catch (IOException e) {
            // 卧槽我加入设置key,value失败,肯定调到这个逻辑
            return false;
        } finally {
            if (fileWriter != null) {  // 还是这样关比较好,万一报错就tm关不了
                try {
                    fileWriter.flush();
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

}

8.File 

在java中file对象表示文件、目录的抽象表示形式。

 案例:递归实现遍历文件目录

public class FileDemo {
    public static void main(String[] args) {
        getChildrenFile("src",1);
    }


    // 递归则子文件所有目录
    public static void getChildrenFile(String fileName,int y){ // fileName 文件路径名,y 是目录等级
        File file = new File(fileName);
        StringBuffer stb = new StringBuffer();
        // 根据目录等级追加几条 "-"
        for (int i = 0; i < y; i++) {
            stb.append("-");
        }
        // 遍历子文件
        for (String name: file.list()) {
            System.out.println(stb + name); // 目录等级 + 文件路径名,并且换行
            String childrenName = fileName + "/"+name;
            if(new File(childrenName).isDirectory()){ // 判断子文件是否是递归,是的话仍执行
                getChildrenFile(childrenName,y+1); // 同样下一级目录等级 + 1
            }
        }
      }

    }

参考资料

Java IO流 详解(字节流、字符流、输入流、输出流、刷新)_输入流 输出流 更新流_肥兄的博客-CSDN博客

 Java IO流(超详细!)_一个快乐的野指针~的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/Qhx20040819/article/details/132086878