IO流学习笔记(学自b站老杜)

本文深入讲解Java IO流的概念、分类及常见操作,包括输入输出流、字节流与字符流的区别,以及FileInputStream、FileOutputStream等16种流的具体用法,辅以实例代码演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO流

1.什么是IO?

通过IO可以完成硬盘文件的读和写

在这里插入图片描述

2.IO的分类

  • 按照流的方向 :输入流 输出流

    • 以内存为参照物

      • 往内存中去为输入(Input),或者叫读(Read)

      • 往内存中出来,叫做输出(Output),也叫做写(Write)

  • 按找读取数据方式的不同 :字节流 字符流

    • 以字节的方式读取数据,一次读取1个字节,等于一次读取8个二进制位。万能流,什么都可以读取。字节流

      • 假设文件file.txt 里面的内容是 a 湖南,采用字节流读取

        第一次读:一个字节,读到 ‘a’

        第二次读:一个字节,读到 ’湖‘ 字符的一半

        第三次读:一个字节,读 ’湖‘ 字符的另外一半

    • 按字符的方式读取,一次读取一个字符,只能读取纯文本文件。txt结尾

      • 假设文件file.txt 里面的内容是 a 湖南,采用字符流读取

        第一次读:’a‘ 字符(’a‘字符在window系统中占一个字节)

        第二次读:’湖‘ 字符 (’湖‘字符在Windows系统中占有2个字节)

3.IO的四大家族

3.1 流的四大家族首领:都是抽象类
  • Java.io.InputStream 字节输入流

  • Java.io.OutputStream 字节输出流

  • Java.io.Reader 字符输入流

  • java.io.Writer 字符输出流

  • 只要类名以Stream结尾的都是字节流,以“Reader/Writer”结尾的都是字符流

  • 所有的流都实现了 Closeable接口,都是可关闭的

  • 流毕竟是一个管道,内存和硬盘之间的通道,用完之后要关闭。会占有很多资源

3.2 输出流
  • 所有的输出流都实现类Java.io.Flushable接口,都是课刷新的
  • 输出流在最终输出之后,一定要flush()
  • 刷新的作用就是清空管道,将管道中剩余为输出的数据强行输出
  • 如果没有flush() 可能会导致丢失数据

4.java.io包下需要掌握流有16个

  • 文件专属:
    • java.io.FileInputStream
    • java.io.FileOutputStream
    • java.io.FileReader
    • java.io.FileWriter
  • 转换流(将字节流转换为字符流)
    • java.io.InputStreamReader
    • java.io.OutputStreamWriter
  • 缓冲流专属
    • java.io.BufferedReader
    • java.io.OutputStreamWriter
  • 数据流专属
    • java.io.DataInputStream
    • java.io.DataOutputStream
  • 标准输出流
    • java.io.PrintWriter
    • java.io.PrintStream
  • 对象专属流
    • java.io.ObjectInputStream
    • java.io.ObjectOutputStream

5.FileInputStream

  • java.io.FileInputStream读取数据
    • 字节输入流是万能的,任何文件类型都可以读

    • 字节的方式完成输入/读的操作(从硬盘到内存)

    • 已经到文件的末尾了,就返回-1

    • 汉字先读取半个,空格也是个字符

    • 避免硬盘与内存交互频繁,为了提交执行效率,一般使用btye[ ]数组

    • idea默认的当前路径是工程Project的根(相对路径)

      public class FileInputStreamTest01 {
      
          public static void main(String[] args) {
              FileInputStream fis = null;
              try {
                  //创建文件字节输入流对象  绝对路径
                  fis = new FileInputStream("F:/IO流/temp.txt");
      
                  //准备一个数组
                  byte[] bytes = new byte[4];
                  int readCount = 0;
                  //开始读取
                  while ((readCount=fis.read(bytes))!= -1) {  //文件的末尾了,就返回-1
                      //把byte数组转换成字符串,读到多少转换多少
                      System.out.print(new String(bytes,0,readCount));
                  }
      
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              } finally {
                  if (fis == null) {  //避免空指针异常
                      //关闭流的前提是;流不为空
                      try {
                          fis.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      
      }
      

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

  • java.io.FileInputStream的其他方法;
    • int available() ; 返回当前流中剩余没有读到的字节数量

      • 具体用法

        public class FileInputStreamTest02 {
           public static void main(String[] args) {
        
            FileInputStream fis = null;
            try {
                fis = new FileInputStream("F:/IO流/temp.txt");
                //不太适合大文件,因为byte数组不能太多
                System.out.println("获取总字节数:"+fis.available());
                byte[] bytes = new byte[fis.available()];
                //不需要循环了,直接读一次就ok
                int readCount = fis.read(bytes);
                System.out.println(new String(bytes));
        
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
         }
        }
        
    • int long skip(long n); 跳过几个字节不读取

      • 具体用法

        public class FileInputStreamTest02 {
        
            public static void main(String[] args) {
        
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream("F:/IO流/temp.txt");
                 	//skip跳过几个字节不读取
                    fis.skip(6);
                    System.out.println(fis.read());
        
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
        }
        

6.FileOutputStream

  • java.io.FileOutputStream输出数据
    • 文件字节输出流,负责写

    • 从内存到硬盘

    • 写完之后一定要刷新

    • 文件不存在的时候会自动新建

    • 不以追加方式new,会将原文件清空,然后重新写入

      • 具体demo

        public class FileOutputStreamTest01 {
        
            public static void main(String[] args) {
                FileOutputStream fos = null;
        
                try {
                    //myFile不存在的时候会自动新建
                    //不加true会将源文件清空
                    fos = new FileOutputStream("myFile",true);
                    //开始写
                    byte[] bytes = {97,98,99,100};
                    //将byte数组全部写出
                    fos.write(bytes);   // abcd
                    //将byte数组的一部分写出
                    fos.write(bytes,0,2);  //再写出ab
        
                    //字符串
                    String str = "我是中国人";
                    //将字符串转换为byte数组
                    byte[] bs = str.getBytes();
                    //写
                    fos.write(bs);
        
                    //写完之后,最后一定要刷新
                    fos.flush();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
        }
        

7.FileInputStream+FileOutputStream完成文件的拷贝

  • 字节流拷贝文件的时候,文件类型随意

    public class CopyTest1 {
    
        public static void main(String[] args) {
            FileInputStream fis = null;
            FileOutputStream fos = null;
    
            try {
                //创建一个输入流对象
                fis = new FileInputStream("D:\\学习与工作软件\\笔记\\typora-setup-x64.exe");
                //创建一个输出流对象
                fos = new FileOutputStream("D:\\休闲娱乐\\游戏\\typora-setup-x64.exe");
    
                //核心:一边读一边写
                byte[] bytes = new byte[1024 * 1024];  //一次最多拷贝1MB
                int readCount = 0;
                while ((readCount = fis.read(bytes))!= -1) {
                    fos.write(bytes,0,readCount);
                }
                //刷新
                fos.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {  //一起try,可能会影响到另一个流的关闭
                if (fos == null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis == null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

8.FileReader

  • 文件字符输入流,只能读取普通文本

    • 一次读取一个字符,比如字节流读取一个汉字只能先读一半

      public class FileReaderTest {
      
          public static void main(String[] args) {
              FileReader reader = null;
              try {
                  //创建文件字符输入流
                  reader = new FileReader("F:/IO流/temp.txt");
                  //开始读取
                  char[] chars = new char[4];  //一次读取4个字符
                  int readCount = 0;
                  while ((readCount = reader.read(chars)) != -1){
                      System.out.print(new String(chars,0,readCount));
                  }
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              } finally {
                  if (reader != null) {
                      try {
                          reader.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      

9.FileWriter

  • 文件字符输出流,写

  • 只能输出普通文本

  • 每次执行会清空,重新写。可追加

    public class FileWriterTest {
    
        public static void main(String[] args) {
            FileWriter out = null;
            try {
                //创建文件字符输出流对象
                out = new FileWriter("file"); //每次执行会清空,重新输。可追加
                //开始写
                char[] chars = {'中','国','人'};
                out.write(chars);
                out.write("我是一名工程师");
                //刷新
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }
    

10.FileReader+FileWriter拷贝文件

  • 只能拷贝普通文件

    public class CopyTest2 {
    
        public static void main(String[] args) {
            FileReader in = null;
            FileWriter out = null;
            try {
                //读
                in = new FileReader("src\\com\\lcy\\io\\CopyTest1.java");
                //写
                out = new FileWriter("CopyTest1.java");
                //一边读,一边写
                char[] chars = new char[1024 * 512];//1MB
                int readCount = 0;
                while ((readCount=in.read(chars))!=-1){
                    out.write(chars,0,readCount);
                }
                //刷新
                out.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (in == null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }
    

11.BufferedReader

  • 使用这流的时候,不需要自定义数组,自带缓冲流

  • 一个流的构造方法中需要一个流的时候,被传进来的流叫做:节点流

  • 外部包装的流叫做:包装流/处理流。是相对而言的

  • readLine方法读取一个文本行,但不带换行符

  • 对于包装流来说,只需要关闭最外层的就行,里面的会自动关闭

    public class BufferedReaderTest01 {
    
        public static void main(String[] args) throws Exception {
    
            FileReader reader = new FileReader("CopyTest1.java");
            //当一个流的构造方法中需要一个流的时候,被传进来的流叫:节点流
            //外部包装的这个流叫:包装流/处理流
            //当前程序:FileReader就是节点流,BufferedReader就是包装流/处理流
            BufferedReader br = new BufferedReader(reader);
    
            //br.readLine()方法读取一个文本行,但不带换行符
            String s = null;
            while ((s = br.readLine())!= null) {
                System.out.println(s);
            }
    
            //关闭流:(对于包装流来说,只需要关闭最外层的就行,里面的会自动关闭)
            br.close();
        }
    }
    
  • 此构造方法只能传一个字符流

  • 字节流需要进行转换流转换

    public class BufferedReaderTest02 {
    
        public static void main(String[] args) throws Exception {
            //字节流
            FileInputStream in = new FileInputStream("CopyTest1.java");
    
            //通过转换流转换(InputStreamReader将字节流转换为字符流)
            //in是节点流,reader是包装流
            InputStreamReader reader = new InputStreamReader(in);
    
            //这个构造方法只能传一个字符流
            //reader是节点流,br是包装流
            BufferedReader br = new BufferedReader(reader);
    
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
    
            //关闭
            br.close();
        }
    }
    

12.BufferedWirter

  • 示例

    public class BufferedWriterTest01 {
    
        public static void main(String[] args) {
    
            try {
                //带有缓冲区的字符输出流
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test",true)));
                //开始写
                out.write("hello world");
                out.write("\n");
                out.write("hello kitty!");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    

13.DataOutputStream

  • 数据专属的流
  • 可以将数据连同数据的类型一起写入文件
  • 这个文件不是普通文本类型
public class DataOutputStreamTest {

    public static void main(String[] args) {
        try {
            //创建数据专属的字节输出流
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("data"));
            //写数据
            byte b = 100;
            short s = 200;
            int i = 300;
            long l = 400L;
            float f = 3.0f;
            double d = 3.14;
            //写  把数据以及数据的类型一起带进去
            dos.writeByte(b);
            dos.writeShort(s);
            dos.writeInt(i);
            dos.writeLong(l);
            dos.writeFloat(f);
            dos.writeDouble(d);
            //刷新
            dos.flush();
            //关闭
            dos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

14.DataInputStream

  • 数据字节输入流

  • DataOutputStream写的文件,只能使用DataInputStream去读,并需要提前知道写入的顺序

  • 读的顺序需要和写的顺序一致,才可正常取出数据

    public class DataInputStreamTest {
    
        public static void main(String[] args) {
            try {
                DataInputStream dis = new DataInputStream(new FileInputStream("data"));
                //开始读  读写顺序需要一致
                byte b = dis.readByte();
                short s = dis.readShort();
                int i = dis.readInt();
                long l = dis.readLong();
                float f = dis.readFloat();
                double d = dis.readDouble();
    
                System.out.println(b);
                System.out.println(s);
                System.out.println(i);
                System.out.println(l);
                System.out.println(f);
                System.out.println(d);
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    

15.PrintStream

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

  • 可以改变输出方向,不再指向控制台

    public class PrintStreamTest01 {
    
        public static void main(String[] args) {
            //联合写
            System.out.println("Hello world!");
    
            //分开写,这些输出到控制台
            PrintStream ps = System.out;
            ps.println("张三");
            ps.println("李四");
            ps.println("王五");
    
            try {
                //可以改变标准输出流的输出方向
                PrintStream printStream = new PrintStream(new FileOutputStream("log",true));
                //修改了输出方向,不再到控制台,到log文件
                System.setOut(printStream);
                //再输出
                System.out.println("hello world");
                System.out.println("hello lcy");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    
    }
    

16.日志工具

  • 日志工具类

    public class Logger {
    
        /**
         * 记录日志的方法
         * @param msg
         */
        public static void log(String msg){
            try {
                //指向一个日志文件
                PrintStream out = new PrintStream(new FileOutputStream("log.txt"), true);
                //改变输出方向
                System.setOut(out);
                //日期当前时间
                Date nowTime = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
                String strTime = sdf.format(nowTime);
                System.out.println(strTime+":"+msg);
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    
    }
    
  • 测试类

    public class LogTest {
    
        public static void main(String[] args) {
            //测试工具类是否好用
            Logger.log("掉用了System类的gc()方法,建议启动垃圾回收");
            Logger.log("调用了UserService的方法");
            Logger.log("用户尝试进行登陆");
        }
    
    }
    
  • log.txt

    2020-05-05 11:53:10 930:掉用了System类的gc()方法,建议启动垃圾回收
    2020-05-05 11:53:10 961:调用了UserService的方法
    2020-05-05 11:53:10 962:用户尝试进行登陆
    

17.File

  • 常用方法

    • File和四大家族没关系,所以不能完成文件的读写操作

    • File对象代表的是文件和目录路径名的抽象表示形式

      • 练习1

        public class FileTest01 {

        public static void main(String[] args) throws IOException {
        
            //创建一个新目录
            File file = new File("F:\\file");
        
            if (!file.exists()) {  //file.exists()判断是否存在
                file.createNewFile();  //以文件的形式创建
                file.mkdir();   //以目录的形式创建
            }
        
            File f2 = new File("F:a/b/c");
            if (!f2.exists()) {
                //多重目录的形式创建
                f2.mkdirs();
            }
        
            File f3 = new File("F:a/b/c");
            //获取文件的父路径
            String parentPath1 = f3.getParent();
            File parentPath2 = f3.getParentFile();
            //F:\\a\b
            System.out.println("获取的绝对路径是:"+parentPath2.getAbsolutePath());  
            System.out.println(parentPath1);  //F:\a\b
        }
        
      • 练习2

        public class FileTest02 {
        
            public static void main(String[] args) {
        
                File f1 = new File("F:\\计网\\答题卡\\计网2016十月.txt");
                //获取文件名
                System.out.println("文件名:"+f1.getName());  //文件名:计网2016十月.txt
        
                //判断是否是一个目录
                System.out.println(f1.isDirectory());   //false
        
                //判断是否是一个文件
                System.out.println(f1.isFile());   //true
        
                //获取文件最后一次修改时间
                long haoMiao = f1.lastModified();  //这个毫秒是1970到现在的总毫秒数
                //将总毫秒数转换成日期
                Date time = new Date(haoMiao);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy--MM-dd HH:mm:ss SSS");
                String strTime = sdf.format(time);
                System.out.println(strTime);   //2020--03-06 17:24:20 577
        
                //获取文件大小
                System.out.println(f1.length());   //2902字节
        
            }
        
        }
        
      • 练习3

        public class FileTest03 {
        
            public static void main(String[] args) {
                //File[] listFiles()
                //获取当前目录下所有的子文件
                File f = new File("F:\\计网\\答题卡");
                File[] files = f.listFiles();
                for (File file :files) {
                    System.out.println(file.getAbsolutePath());   //获取绝对路径
                    System.out.println(file.getName());   //获取文件名
                }
            }
        
        }
        

17 .文件夹Copy(递归)!!!!!!!!有bug

public class CopyAll {

    public static void main(String[] args) {
        //拷贝源
        File srcFile = new File("F:\\计网");
        //拷贝目标
        File destFile = new File("D:");
        //调用方法拷贝
        copyDir(srcFile,destFile);
    }

    /**
     * 拷贝目录
     * @param srcFile  拷贝源
     * @param destFile  拷贝目标
     */
    private static void copyDir(File srcFile, File destFile) {
        if (srcFile.isFile()){
            //如果srcFile是一个文件的话,递归结束
            //是文件的时候需要拷贝
            FileInputStream in = null;
            FileOutputStream out = null;
            try {
                //读这个文件
                in = new FileInputStream(srcFile);
                //写到这个文件中
                String path = (destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath() : destFile.getAbsolutePath()+ "\\") +srcFile.getAbsolutePath().substring(3);
                System.out.println(path);
                out = new FileOutputStream(path);
                //一边读一边写
                byte[] bytes = new byte[1024 * 1024];  //一次复制1MB
                int readCount = 0;
                while ((readCount = in.read(bytes)) != -1) {
                    out.write(bytes,0,readCount);
                }
                //刷新
                out.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return;
        }

        //获取源下面的子目录
        File[] files = srcFile.listFiles();
        for (File file :files) {
            //获取所有文件的绝对路径
            //System.out.println(file.getAbsolutePath());

            if (file.isDirectory()) {
                //新建对应的目录
                //F:\\计网  源目录
                //D:\\计网
                String srcDir = file.getAbsolutePath();
                String destDir = (destFile.getAbsolutePath().endsWith("\\")?destFile.getAbsolutePath() : destFile.getAbsolutePath()+ "\\") +srcDir.substring(3);
                File newFile = new File(destDir);
                if (!newFile.exists()){
                    newFile.mkdirs();
                }
            }

            //递归调用
            copyDir(file,destFile);
        }
    }

}

18.ObjectOutputStream与ObjectInputStream

  • 参与序列化和反序列化的对象,必须实现Serializable接口
  • 通过源码发现,Seriablizable只是一个标志接口,起标识作用
  • JVM看到这个接口,会为该类生成一个序列化版本号

在这里插入图片描述

  • Java中线通过类名进行对比,如果类名一样靠序列化版本号进行区分

  • 不同的人编写了同一个类,两个类确实不是同一个,这个时候版本号就起作用了(优点)

  • 自动生成版本号的缺点是一旦代码确定,不能进行后续的修改

  • 建议给类提供一个固定不变的序列化版本号

  • ObjectOutputStreamTest01序列化

    public class ObjectOutputStreamTest01 {
    
        public static void main(String[] args) throws Exception {
            //创建Java对象
            Stu stu = new Stu(111, "张三");
            //序列化
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stu"));
    
            //序列化对象
            oos.writeObject(stu);
    
            //刷新
            oos.flush();
            //关闭
            oos.close();
        }
    
    }
    
  • 实体类

    public class Stu implements Serializable {
    
        private static final long serialVersionUID = -1910710510701402051L; //虚拟机先通过类名,然后通过版本号区分
    
        //过了很久,Stu这个类源代码改动
        //源码改动之后,需要重新编译,生成了全新的字节码文件
        //并且class文件再次运行的时候,Java虚拟机生成的序列化版本号也会发生改变
        private Integer no;
        private String name;
        private String email;
        private int age;
    
        @Override
        public String toString() {
            return "Stu{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    '}';
        }
    
        public Stu() {
        }
    
        public Stu(Integer no, String name) {
            this.no = no;
            this.name = name;
        }
    
        public Integer getNo() {
            return no;
        }
    
        public void setNo(Integer no) {
            this.no = no;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
  • ObjectInputStreamTest01反序列化

    public class ObjectInputStreamTest01 {
    
        public static void main(String[] args) throws Exception {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("stu"));
            //开始反序列化,读
            Object obj = ois.readObject();
            //反序列化回来的是一个学生对象,所以会调用学生对象的toString方法
            System.out.println(obj);   //Stu{no=111, name='张三'}
            //关闭流
            ois.close();
        }
    }
    
  • 序列化集合,可以把对象放在集合中

  • 参与序列化的ArrayList集合以及集合中的元素User都需要实现Serializable接口

    public class ObjectOutputStreamTest02 {
    
        public static void main(String[] args) throws Exception {
            List<User> userList = new ArrayList();
            userList.add(new User(1,"张三"));
            userList.add(new User(2,"李四"));
            userList.add(new User(3,"王五"));
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user"));
            //序列化一个集合,这个集合对象中放了很多其他对象
            oos.writeObject(userList);
            oos.flush();
            oos.close();
    
        }
    }
    
  • 反序列化集合

  • 如果不使用集合,直接存多个对象,反序列化存储的第二个对象会报错

    public class ObjectInputStreamTest02 {
    
        public static void main(String[] args) throws Exception {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user"));
            //判断是不是List集合
            //System.out.println(obj instanceof List);  //true
            /**
             * User{no=1, name='张三'}
             * User{no=2, name='李四'}
             * User{no=3, name='王五'}
             */
            List<User> userList = (List<User>) ois.readObject();
            for (User user :userList) {
                System.out.println(user);
            }
    
            //关闭流
            ois.close();
        }
    
    }
    
  • transient关键字

    public class User implements Serializable {
    
        private Integer no;
        //transient关键字表示游离,不参与序列化
        private transient String name;  //name不参与序列化操作
    
        @Override
        public String toString() {
            return "User{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    '}';
        }
    
        public User() {
        }
    
        public User(Integer no, String name) {
            this.no = no;
            this.name = name;
        }
    
        public Integer getNo() {
            return no;
        }
    
        public void setNo(Integer no) {
            this.no = no;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

19.Io+Properties的联合应用

  • 设计理念

    • 经常改变的数据,单独写在一个文件中,程序动态获取。

    • 配置文件中的内容格式是键值对的时候,叫做配置文件。

    • Properties是专门存放属性配置文件内容的一个类。

    • 属性配置文件key重复的话,value会自动覆盖。最好不要有空格,冒号

      public class IoPropertiesTest01 {
      
          public static void main(String[] args) throws Exception {
              /*
              Properties是一个Map集合,key和value都是String类型
              想将userinfo文件中的数据加载到Properties对象当中
               */
              //新建一个输入流对象
              FileReader reader = new FileReader("userinfo");
      
              //新建一个Map集合
              Properties pro = new Properties();
      
              //调用Properties对象的load方法将文件中的数据加载到Map集合中
              pro.load(reader);  //文件中的数据顺着管道加载daoMap集合中,键值对
      
              //通过key获取value
              String username = pro.getProperty("username");
              System.out.println(username);
          }
      }
      
  • 配置文件

    username=admin
    password=123
            this.no = no;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

19.Io+Properties的联合应用

  • 设计理念

    • 经常改变的数据,单独写在一个文件中,程序动态获取。

    • 配置文件中的内容格式是键值对的时候,叫做配置文件。

    • Properties是专门存放属性配置文件内容的一个类。

    • 属性配置文件key重复的话,value会自动覆盖。最好不要有空格,冒号

      public class IoPropertiesTest01 {
      
          public static void main(String[] args) throws Exception {
              /*
              Properties是一个Map集合,key和value都是String类型
              想将userinfo文件中的数据加载到Properties对象当中
               */
              //新建一个输入流对象
              FileReader reader = new FileReader("userinfo");
      
              //新建一个Map集合
              Properties pro = new Properties();
      
              //调用Properties对象的load方法将文件中的数据加载到Map集合中
              pro.load(reader);  //文件中的数据顺着管道加载daoMap集合中,键值对
      
              //通过key获取value
              String username = pro.getProperty("username");
              System.out.println(username);
          }
      }
      
  • 配置文件

    username=admin
    password=123
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值