• 【Java基础】第六章 | IO流


    目录

    | 总框架

    | 文件路径相关知识

    | Peoperties类与IO流、配置文件*

    | 1.文件流

    文件字节输入流(标准输入流) FileInputStream

    文件字节输出流 FileOutputStream

    文件字符输入流 FileReader

    文件字符输出流 FileWriter

    应用:使用字节流复制文件

    应用:使用字符流复制txt文件

    | 2.缓冲流、转换流

    | 3.数据流

    | 4.标准输出流

    字节打印流(标准输出流)PrintStream

    字符打印流PrintWriter

    应用:制作一个打印日志 + 恢复System输出流指向控制台



    | 总框架

    16个 重要的IO流简介(标蓝的为重点)

    【文件流】

    • 作用:读取文件

    • FileInputStream(字节流 | 标准输入流) FileOutputStream(字节流) FileReader(字符流) FileWriter(字符流)

    【缓冲流】

    • 作用:缓冲流自带缓冲区,使用的时候无需自定义char[ ]或者byte[ ]。

      缓冲流也称为处理流,对文件或者其他目标频繁的操作,效率低,性能差。缓冲流目的是提高程序读取和写出的性能。

    • BufferedInputStream(字节流) BufferedOutputStream(字节流) BufferedReader(字符流) BufferedWriter(字符流)

    【对象流】

    • 作用:将对象序列化和反序列以保存

    • ObjectInputStream(字节流) ObjectOurputStream(字节流)

    【数据流】

    • 作用:可以将数据的类型如 num 是int型一并写入文件。(但是该文件不是文本文件,使用记事本打开是乱码的,有效保证了安全性)

    • DataInputStream(字节流) DataOutputStream(字节流)

    【标准输出流】

    • 作用:FileInputStream是标准输入流,相对的,标准输出流却不是FileOutputStream而是PrintStream

    • PrintStream(字节流 | 标准输出流) PrintWriter(字符流)

    【字节流 转换 字符流】

    • 字节流:按字节读取文件;字符流:按字符读取文件。

    • 作用:把一个传递字节的节点流用于字符流,则我们需要使用转换流,先转化再传递

    • InputStreamReader OutputStreamWriter

    Java IO体系

    • 含有 Stream 的都是字节相关的流,含有 der 的都是字符相关的流


    | 文件路径相关知识

    • 根据测试,文件路径以【当前用户根目录的路径】为相对路径

    • 下面介绍一下File类

      • File类,和下面介绍的流,没有任何关系。File是任意的文件、或者任意的目录。即:“文件和路径名”的抽象表现形式

      • 我们主要需要掌握构造方法、对象方法、及其相关应用

      • 语法如下

    1. File file = new File ( 路径/文件路径 ); //构造方法
    2. file . exists ( ); //判断文件或目录是否存在(存在则返回boolean):
    3. file . isDirectory( ); //判断是否是一个目录(是则返回boolean)
    4. file . isFile( ); //判断是否是一个文件(是则返回boolean)
    5. file . getParent( ); //返回此抽象路径名父目录的路径字符串。若不存在,则返回null
    6. file . getParentFile( ); //返回此抽象路径名父目录的路径的File类对象。不存在则返回null
    7. file . getAbsolutePath( ); //返回此抽象路径名的绝对路径字符串
    8. file . getAbsoluteFile( ); //返回此抽象路径名的绝对路径的File类对象
    9. file . length( ); //获取文件的大小,返回一个表示文件字节大小的long值
    10. file . lastModified( ); //获取文件的最后一次修改时间,返回1970年到现在的毫秒long值
    11. file . listFiles( ); //获取当前目录下所有的子文件及目录,返回一个File数组


    | Peoperties类与IO流、配置文件*

    Properties集合简介

    • 主要用于读取Java的配置文件。

    • Properties是一个Map体系集合类,因为其继承于Hashtable,而Hashtable继承于Dictionary类,实现了Map接口,所以Properties也保留了其相关特性。

    • Properties的特点

      • (1)Properties是Hashtable的子类;

      • (2)Properties类表示了一个可持久的属性集;

      • (3)Properties可以保存在流中或从流中加载;

      • (4)Properties中每个键和对应的值都是一个字符串(String类型);

      • (5)Properties有一个特殊的作用:专门用来加载xxx.properties配置文件。

    Properties的使用

    1. //Properties作为map集合的使用
    2. private static void PropertiesMap() {
    3. Properties pro = new Properties();//不需要加泛型,所有的键值都是object类型
    4. //存储元素
    5. pro.put(001, "张三");
    6. pro.put(002, "李四");
    7. pro.put(003, "王五");
    8. //遍历集合
    9. for(Object key : pro.keySet()) {
    10. System.out.println(key + ":" + pro.get(key));
    11. }
    12. }
    1. /**
    2. * Properties作为集合的特有方法
    3. * 0bject setProperty(String key,String value):设置类合的链和值,都是String类型,底层调用Hashtable方法put
    4. * string getProperty ( String key):使用此属性列表中指定的性搜索属性
    5. * Set stringPropert yNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
    6. */
    7. private static void SpecialMethod() {
    8. Properties pro = new Properties();
    9. pro.setProperty("001", "张三");//键值都是String类型
    10. pro.setProperty("002", "李四");
    11. pro.setProperty("003", "王五");
    12. System.out.println(pro.getProperty("001"));//根据键搜索属性
    13. System.out.println(pro.getProperty("0011"));//没有时返回null
    14. System.out.println(pro);
    15. Set s = pro.stringPropertyNames();//返回一个不可修改的键集,其中键及其对应的值是字符串
    16. System.out.println(s);
    17. for(String key : s) {
    18. System.out.println(key + ":" + pro.getProperty(key));
    19. }
    20. }

    Peoperties 通过 IO,结合 .properties文件使用

    1. //集合中数据保存到文件
    2. Properties pro = new Properties();
    3. pro.setProperty("001", "张三");//键值都是String类型
    4. pro.setProperty("002", "李四");
    5. pro.setProperty("003", "王五");
    6. System.out.println(pro);
    7. FileWriter fw = new FileWriter("Properties.properties");
    8. pro.store(fw,null);//不想添加描述信息就令第二个参数为null
    9. //数据保存为XML格式文件
    10. //storeToXML(OutputStream os, String comment, String encoding)使用指定的编码方式表示此表中包含的所有属性的XML文档
    11. FileOutputStream f1 = new FileOutputStream("PropertiesXML.XML");
    12. pro.storeToXML(f1, null);
    1. //文件中数据加载到集合
    2. Properties prop = new Properties();
    3. FileReader fr = new FileReader("Properties.properties");
    4. prop.load(fr);
    5. //将此属性列表打印到指定的输出流。此方法对于调试很有用
    6. prop.list(System.out);
    7. //System.out.println(prop);
    8. //从内容为XML格式的文件中读取数据加载为集合
    9. FileInputStream f2 = new FileInputStream("PropertiesXML.XML");
    10. prop.loadFromXML(f2);
    11. prop.list(System.out);
    12. //System.out.println(prop);
     

    | 1.文件流

    • FileInputStream(字节流) FileOutputStream(字节流) FileReader(字符流) FileWriter(字符流)

    • 字节流可以读取任意类型的文件,而字符流只能读取 文本文件 .txt

    文件字节输入流(标准输入流) FileInputStream

    1. public static void main(String[] args){
    2. try{
    3. //创建FileInputStream对象
    4. FileInputStream in = new FileInputStream(String path); //不追加读写
    5. //FileInputStream in = new FileInputStream(String path , true); //追加读写
    6. //创建字节数组
    7. byte[] b = new byte[1024];
    8. int len = 0;
    9. //一次读取最多字节数组大小的字节长度,并把读取到的字节赋值给字节数组
    10. while((len = in.read(b)) != -1){
    11. System.out.println(new String(b , 0 , len));
    12. }
    13. //关闭IO流
    14. in.close();
    15. }catch(Exception e){
    16. e.printStackTrace();
    17. }
    18. }

    文件字节输出流 FileOutputStream

    1. public static void main(String[] args){
    2. try{
    3. //创建FileOutputStream对象
    4. FileOutputStream out = new FileOutputStream(String path);
    5. String str = "XXX";
    6. //写入字节
    7. out.write(str.getBytes());
    8. //缓冲、关闭IO流
    9. out.flush();
    10. out.close();
    11. }catch(Exception e){
    12. e.printStackTrace();
    13. }
    14. }

    文件字符输入流 FileReader

    1. public class FileReaderClass {
    2. public static void main(String[] args) {
    3. FileReader reader = null;
    4. try {
    5. //创建字符输入流
    6. reader = new FileReader("F:\\Java\\IOPractice\\FileReaderTXT.txt");
    7. //创建字符数组和中介数i
    8. char[] array = new char[2];
    9. int i=0;
    10. //一次读取最多字符数组长度的字符个数,并把字符赋值给字符数组
    11. while((i=reader.read(array))!=-1){
    12. String mid = new String(array,0,i);
    13. System.out.print(mid);
    14. }
    15. } catch (IOException e) {
    16. e.printStackTrace();
    17. }finally{
    18. try {
    19. reader.close();
    20. } catch (IOException e) {
    21. e.printStackTrace();
    22. }
    23. }
    24. }
    25. }

    文件字符输出流 FileWriter

    1. public class FileWriterClass {
    2. public static void main(String[] args) {
    3. FileWriter out = null;
    4. try {
    5. out = new FileWriter("F:\\Java\\IOPractice\\FileWriterTXT.txt",true);
    6. char[] array = {'C','S'};
    7. out.write(62); // >
    8. out.write(array); //可莉
    9. out.write("klee"); //klee
    10. out.flush();//输出流要记得刷新
    11. } catch (IOException e) {
    12. e.printStackTrace();
    13. }finally{
    14. try {
    15. out.close();
    16. } catch (IOException e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }
    21. }

    应用:使用字节流复制文件

    1. //复制文件
    2. public class CopyFile {
    3. public static void main(String[] args) {
    4. //外部建立一个空输入流、输出流
    5. FileInputStream filein = null;
    6. FileOutputStream fileout = null;
    7. try {
    8. //创建输入流、输出流对象
    9. filein = new FileInputStream("F:\\Java\\IOPractice\\copyTXT.txt");
    10. fileout = new FileOutputStream("F:\\Java\\IOPractice\\" +"copyGoalTXT.txt",true);//追加读写
    11. //【核心】一边读,一边写
    12. //假设我们复制一个大小为1738kb的文件
    13. byte[] bytes = new byte[1024]; /*一次copy 1024k 的文件*/
    14. int readCount = 0;
    15. while((readCount = filein.read(bytes)) != -1){
    16. fileout.write(bytes,0,readCount);
    17. }
    18. //刷新输出流
    19. try {
    20. fileout.flush();
    21. } catch (IOException e) {
    22. e.printStackTrace();
    23. }
    24. } catch (IOException e) {
    25. e.printStackTrace();
    26. }finally{
    27. //关闭输入流(建议分开try..catch,不至于一个异常 都无法关闭)
    28. try {
    29. filein.close();
    30. } catch (IOException e) {
    31. e.printStackTrace();
    32. }
    33. //关闭输出流
    34. try {
    35. fileout.close();
    36. } catch (IOException e) {
    37. e.printStackTrace();
    38. }
    39. }
    40. }
    41. }

    应用:使用字符流复制txt文件

    1. public class copyTXT {
    2. public static void main(String[] args) {
    3. FileReader in = null;
    4. FileWriter out = null;
    5. try {
    6. in = new FileReader("F:\\JAVA\\IOPractice\\copyTXT.txt");
    7. out = new FileWriter("F:\\JAVA\\IOPractice\\copyGoalTXT.txt");
    8. char[] charArr = new char[1024];
    9. int readCount = 0;
    10. while((readCount = in.read(charArr))!=-1){
    11. out.write(charArr,0,readCount);
    12. }
    13. out.flush();
    14. } catch (IOException e) {
    15. e.printStackTrace();
    16. }finally{
    17. try {
    18. in.close();
    19. } catch (IOException e) {
    20. e.printStackTrace();
    21. }
    22. try {
    23. out.close();
    24. } catch (IOException e) {
    25. e.printStackTrace();
    26. }
    27. }
    28. }
    29. }

    | 2.缓冲流、转换流

    缓冲流简介

    • BufferedInputStream(字节流) BufferedOutputStream(字节流) BufferedReader(字符流) BufferedWriter(字符流)

    • 缓冲流也称为处理流,对文件或者其他目标频繁的操作,效率低,性能差。缓冲流目的是提高程序读取和写出的性能。

    • 缓冲流的基本原理,是创建流对象时候,会创建一个内置的默认大小的缓冲区数组,通过缓冲区书写.使得性能大大提升

      因此相比于 文件流,缓冲流无需通过数组作为中介进行流的传输

    缓冲流的使用

    • 以 BufferedWriter 缓冲输入字节流 为例。关键在于其创建对象时的构造参数:

      • 可以直接使用【文件输入字符流的对象】作为参数

      • 也可以使用【文件输入字节流】通过【字节流转为字符流 的对象】作为参数

    转换流简介

    • InputStreamReader OutputStreamWriter

    • 转换流用于把【字节流转为字符流】

    代码示例(下列代码演示了缓冲流+转换流的搭配使用)

    1. package com.zhan02;
    2. import java.io.*;
    3. public class BufferedWriterTest {
    4. public static void main(String[] args) throws IOException {
    5. FileOutputStream fileOutputStream = new FileOutputStream("working.txt",true);
    6. //通过创建转换流对象,利用【文件输出字节流对象】创建了【文件输出字符流对象】
    7. OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
    8. //构造参数内部传入的是FileOutputStream的对象,表示属于FileOutputStream的缓冲
    9. BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
    10. //这样写也行,相当于直接传入一个【文件字符输出流】给【文件缓冲字符输出流】作为创建对象的构造函数的参数
    11. //BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(String path));
    12. bufferedWriter.write("追加成功!");
    13. bufferedWriter.flush();
    14. bufferedWriter.close();
    15. }
    16. }
    • FileOnputStream类用来指向working.txt文本,构造方法里的true表示当进行写入是以追加形式写入

    • OutputSteamWriter用于从字节流转换到字符流

    • BufferWriter就是属于字符型的缓冲流


    | 3.数据流

    数据流简介

    • DataInputStream(字节流) DataOutputStream(字节流)

    • 作用:

      • 可以将数据的类型如 num 是int型一并写入文件。(但是该文件不是文本文件,使用记事本打开是乱码的,有效保证了安全性)

      • 保障数据安全性:输出的文件很可能为乱码,只有通过数据流方式读取时才能解码

    • 因为输入时是按顺序输入的,所以读取时也需要按顺序读取,否则会报错

    代码示例

    1. public static void main(String[] args) {
    2. DataOutputStream dos = null;
    3. DataInputStream dis = null;
    4. try {
    5. //创建写出,读入流文件,构造器中放入节点流对象.
    6. dos = new DataOutputStream(new FileOutputStream("Test.txt"));
    7. dis = new DataInputStream(new FileInputStream("Test.txt"));
    8. dos.writeInt(20);
    9. dos.writeUTF("Tom");
    10. dos.writeChar('M');
    11. System.out.println(dis.readInt());
    12. System.out.println(dis.readUTF());
    13. System.out.println(dis.readChar());
    14. } catch (IOException e) {
    15. e.printStackTrace();
    16. } finally {
    17. if (dos != null) {
    18. try {
    19. dos.close();
    20. } catch (IOException e) {
    21. e.printStackTrace();
    22. }
    23. }
    24. if (dis != null){
    25. try {
    26. dis.close();
    27. } catch (IOException e) {
    28. e.printStackTrace();
    29. }
    30. }
    31. }
    32. }
     

    | 4.标准输出流

    标准输出流简介

    • PrintStream(字节流) PrintWriter(字符流)

    • 作用:FileInputStream是标准输入流,相对的,标准输出流却不是FileOutputStream而是PrintStream

    • 标准输出流不需要手动 close( )关闭

      如:PrintStream ps = System.out; ps.println("System本身就是一个标准输出流,其输出终点是控制台")

    字节打印流(标准输出流)PrintStream

    • 通过PrintStream输出内容到文件

    1. PrintStream ps=new PrintStream("mydir\\ps.txt");
    2. ps.write(97); //97写入ps.txt文件

    通过PrintStream改变System.out的输出方向(默认是控制台,但是可以改变到文件中)

    1. PrintStream ps = new PrintStream("mydir\\ps.txt");
    2. System.setOut(ps); //改变System.out的输出方向(默认是控制台,但是可以改变到文件中)
    3. System.out.println(97); //97写入ps.txt文件
    4. System.setOut(System.out); //系统标准的输出流方向还可以改回控制台

    字符打印流PrintWriter

    1. //不会自动flush
    2. PrintWriter pw=new PrintWriter("mydir\\java.txt");
    3. pw.write("hello");//要刷新
    4. pw.flush();
    5. pw.write("\r\n");//换行
    6. pw.println("hello");
    7. pw.flush();
    8. //自动flush
    9. PrintWriter pw=new PrintWriter("mydir\\java.txt",true);
    10. pw.write("hello");//要刷新
    11. pw.write("\r\n");//换行

    应用:制作一个打印日志 + 恢复System输出流指向控制台

    • 利用标准输出流对象,结合System.setOut(new PrintStream)方法,改变System.out.println() 的输出方向,由默认的输出到控制台转变为输出到指定文件中。

    • 如果要恢复System输出流指向控制台,则需要在最开始保存指向控制台的指针:PrintStream ps = System.out;

    1. public class PrintStreamClass {
    2. public static void main(String[] args) {
    3. try {
    4. log("第一次使用日志");
    5. } catch (FileNotFoundException e) {
    6. e.printStackTrace();
    7. }
    8. }
    9. public static void log(String message) throws FileNotFoundException {
    10. //保存当前指向控制台的指针
    11. PrintStream ps = System.out;
    12. //Step1.设置一个以FileOutputStream参数为构造方法的标准输出流PrintStream printstream
    13. String path = "log.txt";
    14. PrintStream printStream = new PrintStream(new FileOutputStream(path));
    15. System.setOut(printStream);
    16. //Step2.把printStream作为System.setOut的参数传递进来,改变输出方向为log.txt文本
    17. Date date = new Date();
    18. SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
    19. String time = sdf.format(date);
    20. //Step3.获取当前的时间字符串,输出时间和信息 到文本文件log.txt中
    21. System.out.println(time+":"+message);
    22. //恢复System输出流的方向(需要使用原先保存的控制台指针)
    23. System.setOut(ps);
    24. System.out.println(22);
    25. }
    26. }
  • 相关阅读:
    Django学习笔记:第二章django的安装和创建应用
    MongoDB数据库的安装和使用
    随机流-RandomAccessFile
    云表:“智、数”结合,低代码赋能制造业,入局者赢
    【Proteus仿真】【STM32单片机】出租车计价器
    Vue 路由
    leetcode416分割等和子集刷题打卡
    Java版 求平均年龄01星球有学长若干名, 给出每个学长的年龄, 求01星球学长的平均年龄, 保留小数点后两位
    【Mybatis】mybatis使用与理解
    Android - toolbar 优化 title修改边距和navigation icon修改padding值
  • 原文地址:https://blog.csdn.net/m0_57265007/article/details/127946035