java_IO相关

一、流的概念

  • 概念:内存与存储设备之间传输数据的通道。

二、流的分类

  • 按方向:
    • 输入流:将存储设备中的内容读入到内存中。
    • 输出流:将内存中的内容写入到存储设备中。
    • image-20220227162951185
  • 按单位:
    • 字节流:以字节为单位,可以读写所有数据。
    • 字符流:以字符为单位,只能读写文本数据。
  • 按功能:
    • 节点流:具有实际传输数据的读写功能,如FileInputStream。
    • 过滤流:在节点流的基础之上增强功能,如BuffeeredInputStream。

三、字节流

  • 字节流的父类(抽象类):

    • InputStream:字节输入流(读)image-20220228102508682
    • OutputStream:字节输出流(写)image-20220228102534264
  • 文件字节流

    • FileInputStream

      • public int read(byte[] b) //从流中读取多个字节,将读到的内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1

      • //单字节读取,sp.txt中内容为“abcdefg”
        FileInputStream fis=new FileInputStream("f:\\sp.txt");//可能会抛出异常,先直接抛出
        //1.单个字节读取
        int count=0;
        while((count=fis.read())!=-1) { //将fis读取到的数先赋值给count再进行判断
            System.out.println((char) count);//如果不强转,打印的是ASCII码的值
        }
        //关闭流
        fis.close();
        
      • //多字节读取
        FileInputStream fis=new FileInputStream("f:\\sp.txt");//可能会抛出异常,先直接抛出
        //2.多个字节一起读取
        byte []buf=new byte[3];
        int count1=fis.read(buf);//返回读取的字节数量
        System.out.println(new String(buf));//abc
        System.out.println(count1);//3
        int count2=fis.read(buf);
        System.out.println(new String(buf));//def
        System.out.println(count2);//3
        int count3=fis.read(buf);
        //这种方式输出会输出gef,实际文件中为abcdefg,因为buf中在上次的读取中已经有def了
        System.out.println(new String(buf));//gef
        System.out.println(new String(buf,0,count3));//这样就正确了,打印g
        System.out.println(count3);//1
        //关闭流
        fis.close();
        
      • //对上面的代码进行优化
        FileInputStream fis=new FileInputStream("f:\\sp.txt");//可能会抛出异常,先直接抛出
        //3.对上面的代码进行优化
        byte []buf=new byte[3];//一般为1024
        int count=0;
        //如果不是-1就一直读
        while ((count= fis.read(buf))!=-1){
            System.out.println(new String(buf,0,count));
        }
        //关闭流
        fis.close();
        //最终打印结果为:
        //abc
        //def
        //g
        
    • FileOutputStream

      • public void write(byte[] b) //一次写多个字节,将数组中所有的字节,写入输出流。

      • public class FileOutputDemo {
            public static void main(String[] args) throws Exception{
                FileOutputStream fos=new FileOutputStream("F:\\bbb.txt");
                fos.write(97);
                fos.write('i');
                fos.write('H');
                String a="avbasdjajsd";
                fos.write(a.getBytes());
                fos.close();
                System.out.println("执行完成");
                //写入的数据是按IDE默认编码方式来写的,我的IDE是UTF-8,所以解析时也要用UTF-8来解析,否则可能乱码
            }
        }
        
    • 文件字节流的小例子,copy照片

    • import java.io.FileInputStream;
      import java.io.FileOutputStream;
      
      /**
       * 通过字节流实现图片的复制
       */
      public class PictureCopyDemo {
          public static void main(String[] args) throws Exception{
              FileInputStream fis=new FileInputStream("C:\\Users\\韩信\\Desktop\\DSC_6197.jpg");
              FileOutputStream fos=new FileOutputStream("C:\\Users\\韩信\\Desktop\\DSC_61972.jpg");
              //边读边写
              byte[] buffer=new byte[1024];
              int count;
              while((count=fis.read(buffer))!=-1){//read的返回值为读取的字节个数
                  fos.write(buffer,0,count);//0为数组起始位置,count为写入长度
              }
              fis.close();
              fos.close();
              System.out.println("copy success!");
          }
      }
      

四、字节缓冲流

  • 缓冲流:BufferedInputStream/BufferedOutputStream

    • 提高IO效率,减少访问磁盘的次数
    • 数据存储在缓冲区中,flush是将缓存的内容写入文件中,也可以直接colse
    • 其父类为FilterInputStream /FilterOutputStream ,所谓过滤流就是其他流的功能增强流,为其他流提供服务的,构造方法要传入一个其他流
  • 缓冲输入流

    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    
    /**
     * BufferedInputStream字节缓冲流,过滤流的一种,是一种增强功能的流,其内部自定义了一个缓冲区
     */
    public class BufferedInputStreamDemo {
        public static void main(String[] args) throws Exception {
            BufferedInputStream bis=new BufferedInputStream(new FileInputStream("F:\\sp.txt"));
    //        //单个字节读取,默认buffer为8k(DEFAULT_BUFFER_SIZE = 8192)
    //        int count;
    //        while ((count=bis.read())!=-1){
    //            System.out.print((char)count);
    //        }
            //也可以自定义缓冲区大小
            byte[] buf=new byte[1024];
            int count;
            while((count=bis.read(buf))!=-1){
                System.out.println(new String(buf,0,count));
            }
            bis.close();//默认关闭构造方法中的流
        }
    }
    
  • 缓冲输出流

    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    
    /**
     * BufferedOutputStream实例
     * 该类实现缓冲输出流。
     * 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。
     * 内部维护了一个缓冲区,write时先写入缓冲区,通过flush来写入硬盘
     */
    public class BufferedOutputStreamDemo {
    public static void main(String[]args) throws Exception{
       BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("F:\\buffer.txt"));//可通过构造方法指定缓冲区大小
            for (int i = 0; i < 10; i++) {
                    bos.write((String.valueOf(i)+"helloworld\r\n").getBytes());//i放前面会导致乱码,需要先转成String
                    //内部维护的缓冲区默认大小为8K(8192),
                    // 如果要写入的数据比缓冲区大则会直接写入,否则需要调用flush方法写入
                    //在Windows中:
                    //用\r\n来表示换行
                    //'\r' 回车,回到当前行的行首,而不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖;
                    //'\n' 换行,换到当前位置的下一行,而不会回到行首;
                    //经测试,未得出'\r'、'\n' 的准确结论
                    bos.flush();
            }
            bos.close();//默认会调用flush
            System.out.println("OK");
      }
    }
    

五、对象流

  • ObjectOutputStream/ObjectInputStream

    • 可将内存中的对象写入硬盘或将硬盘内的对象读入内存
    • ObjectOutputStream/ObjectInputStream也是一种过滤流的一种,要基于节点流进行操作
    • 增强了缓冲区功能
    • 增强了读写8种基本数据类型和字符串功能
    • 增强了读写对象的功能
      • readObjec()从流中读取一个对象(反序列化)
      • writeObject(Object obj)向流中写入一个对象(序列化)
  • ObjectOutputStream(序列化)

    //先创建一个Student类并实现Serializable接口
    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    
    public class ObjectOutputStreamDemo {
        public static void main(String[] args) throws Exception{
            ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("F:\\stu.bin"));
            //Student必须实现Serializable接口,此接口元实现方法,是一个标志接口,表示此实现类可以序列化,如果不实现此接口,会抛出异常NotSerializableException
            Student stu=new Student("宋平",25);
            oos.writeObject(stu);
            oos.writeDouble(9.60);
            //flush();
            oos.close();//自动调用flush
            System.out.println("序列化完成");
        }
    }
    
  • ObjectInputStream(反序列化)

    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    
    /**
     * ObjectInputStream反序列化
     */
    public class ObjectInputStreamDemo {
        public static void main(String[] args) throws Exception{
            ObjectInputStream ois=new ObjectInputStream(new FileInputStream("F:\\stu.bin"));
            Object o = ois.readObject();
            Object o1 = ois.readDouble();
            System.out.println(o.toString());
            System.out.println(o1);
        }
    }
    
  • 序列化和反序列化注意事项

    • 序列化类必须要实现Serializable接口

    • 序列化类中的对象如果是个类类型,也需要实现Serializable接口

    • 序列化版本号ID,保证序列化的类和反序列化的类是同一个类

    • 使用transient(瞬间的)修饰属性,则这个属性不能序列化

    • 静态属性不能序列化

    • 多个对象序列化可以用集合

    • private final static long serialVersionUID=100L;//必须声明为final static long序列化的文件会写入serialVersionUID,而反序列化时要进行匹配
      transient//关键字,用于标记属性不参与序列化,以默认值写入序列化文件中,反序列化读出的也是默认值
      

六、字符编码

  • ISO-8859-1:收录了除了ASCII码外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
  • UTF-8(万国码):针对Unicode码表的可变长度字符编码,一般为123个字节。
  • GB2312(国标2312):1995年这前我国采用的编码方式,采用1个或2个字节。
  • GBK:95年后我国采用的编码方式,是对GB2312的扩充,采用1个或2个字节。
  • BIG5(台湾):繁体中文。
  • 各个国家都有不同的编码方式,但是要注意,当编码方式和解码方式不一致时,会出现乱码现象。

七、字符流

  • 引入:用FileInputStream字节流来读取汉字:

    • image-20220311000635945image-20220311000820394

    • import java.io.FileInputStream;
      
      public class ChineseInputDemo {
          public static void main(String[] args) throws Exception{
              FileInputStream fis=new FileInputStream("f:\\hello.txt");
              int count=0;
              while ((count=fis.read())!=-1){
                  System.out.print((char)count);
              }
              fis.close();
          }
      }
      //输出结果:是道士啊
      //可以看出1个汉字在UFT-8中占用3个字节,而字节流是一个字节一个字节的读取,因此会出现乱码
      
  • 字符流:

    • 字符流的父类(抽象类):
      • Reader:字符输入流image-20220311001203308
      • Writer:字符输出流image-20220311001323027
  • 文件字符流(以下两个类是Reader和Writer的间接子类)

    • FileReader:

      • public int read(char[] c)//从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数,如果达到文件的尾部,则返回-1。

      • package IO;
        import java.io.FileReader;
        /****
         * 字符输入流FileReader
         * 按照默认编码方式(UTF-8)读取文件数据
         */
        public class FileReaderDemo {
            public static void main(String[] args) throws Exception{
                FileReader fr=new FileReader("f:\\hello.txt");
        //        int count=0;
        //        //单个字符读取
        //        while ((count=fr.read())!=-1){
        //            System.out.println(Integer.toHexString(count));
        //            System.out.println((char)count);
        //            //662f:对应汉字(是)
        //            //9053:道
        //            //58eb:士
        //            //554a:啊
        //        }
                char[] buf=new char[2];//注意是char数组,不是byte数组,因为读取的是字符
                int count=0;
                while((count=fr.read(buf))!=-1){//这个read方法是读取到buf中
                    System.out.println(new java.lang.String(buf,0,count));
                    //是道
                    //士啊
                }
                fr.close();
            }
        }
        
    • FileWriter:

      • public void write(String str) //一次写多个字符,将b数组中所有字符,写入输出流。

      • import java.io.FileWriter;
        
        public class FileWriterDemo {
            public static void main(String[] args) throws Exception{
                FileWriter fw=new FileWriter("F:\\write.txt");
                char[] buf={'韩','信','\r','\n'};
                for (int i = 0; i < 10; i++) {
                    fw.write(buf);
                    fw.flush();
                }
                fw.close();
                System.out.println("执行完成");
            }
        }
        
  • 用字符流实现文本文件的复制

    • 注意,因为图片等二进制文件无字符编码格式,所以无法用字符流进行复制,要用字节流进行复制

    • package IO;
      
      import java.io.FileReader;
      import java.io.FileWriter;
      
      /**
       * 字符流实现文本文件的copy
       * 注意,字符流不能实现图片等二进制的文件的copy,因为他们是没有字符编码的,从硬盘读到的数据,会按默认编码解码,在写回硬盘,这样与原文件的数据就不一样了
       * 要实现图片等二进制文件的复制,要用字节流
       */
      public class CharStreamCopyDemo {
          public static void main(String[] args) throws Exception{
              //字符流实现文本文件的复制
              //边读边写
              FileReader fr=new FileReader("f:\\han.txt");
              FileWriter fw=new FileWriter("f:\\han1.txt");
              int count=0;
              while ((count=fr.read())!=-1){
                  fw.write(count);
                  fw.flush();
              }
              fr.close();
              fw.close();
              System.out.println("读写完成");
          }
      }
      

八、字符缓冲流

  • 缓冲流:BufferedReader/BufferedWriter

    • 高效读写
    • 支持输入换行符
    • 可以一次写一行、读一行
  • BufferedReader

    • package IO;
      
      import java.io.BufferedReader;
      import java.io.FileReader;
      
      /**
       * 字符缓冲流,一种过滤流
       * 注意:提供了readline方法
       */
      public class BufferedReaderDemo {
          public static void main(String[] args) throws Exception{
              BufferedReader br=new BufferedReader(new FileReader("f:\\han.txt"));
              //第一种方法:自定义缓冲区
      //        char []buf=new char[1024];
      //        int count=0;
      //        while((count=br.read(buf))!=-1){
      //            System.out.println(new String(buf,0,count));
      //        }
              //第二种方法:一行一行读
              String str=null;
              while ((str=br.readLine())!=null){
                  System.out.println(str);
              }
              br.close();
          }
      }
      
  • BufferedWriter:

    import java.io.BufferedWriter;
    import java.io.FileWriter;
    
    public class BufferdWriterDemo {
        public static void main(String[] args) throws Exception{
            BufferedWriter bw=new BufferedWriter(new FileWriter("F:\\write.txt"));
            for (int i = 0; i < 10; i++) {
                bw.write("韩信是个道士啊");
                bw.newLine();//换行,不同OS中不一样,由OS决定,windows中是\r\n,Linux或Mac中为\n
                bw.flush();
            }
            bw.close();
            System.out.println("完成");
        }
    }
    
  • BufferedWriter缓冲区问题:经测试,若指定缓冲区小于8192,都是按照默认8K来进行操作,但是如果指定的缓冲区大于8192,则按照指定缓冲区来调用。

  • package IO;
    
    import java.io.*;
    
    /**
     * 输出转换流:将内存中的字符流按指定格式,以二进制字节的方式写入到硬盘中
     * 实现字符流到字节流的转换
     */
    public class OutputStreamWriterDemo {
        public static void main(String[] args) throws Exception{
            FileOutputStream fos=new FileOutputStream("F:\\sp.txt",true);
            OutputStreamWriter osw =new OutputStreamWriter(fos,"GB2312");
            BufferedWriter bw=new BufferedWriter(osw,2);//通过构造方法来指定缓冲区大小
             char[] buf= new char[16023];
             buf[0]=78;
             bw.write(buf,0,8192);//8193有输出,而8192无输出
           //bw1.flush();
           //bw1.close();
        }
    }
    

九、PrintWriter和PrintStream

  • printWriter和printStream的区别就在于前者为字符打印流,后者是字节打印流,其他都一样

  • package IO;
    import java.io.PrintWriter;
    /**
     * print会直接输出原类型,如97输出97不会转化为a输出
     */
    public class PrintWriterDemo02 {
        public static void main(String[] args) throws Exception{
            PrintWriter pw=new PrintWriter("F:\\print.txt");
            pw.println(97);
            pw.println('a');
            pw.println(2.78);
            pw.println("韩信");
            pw.write(97);//用write输出会输出a且不会换行
            pw.write('a');
            pw.write(String.valueOf(2.79));
            pw.write("韩信");
            pw.flush();
            pw.close();
            System.out.println("perform succeed");
        }
    }
    

十、FileDescriptor(文件描述符)

  • 文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,用于指代被打开的文件,对文件所有 I/O 操作相关的系统调用都需要通过文件描述符。

  • system.out.println的本质是一个printStream

  • FileDescriptor.out就代表在控制台输出,通过阅读源码,个人理解是代表一个虚拟的文件,给一个handle标识,如何实现没读懂,记录一下,以后在说吧- -

  • import java.io.FileDescriptor;
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    
    /**
     * 打印输出流
     */
    public class PrintWriterDemo {
        public static void main(String[] args) throws Exception{
            FileOutputStream out = new FileOutputStream(FileDescriptor.out);
            PrintStream ps=new PrintStream(out);
            ps.println('A');
            ps.close();
        }
    }
    

十一、转换流

  • 也叫桥转换流:InputStreamReader/OutputStreamWriter

  • 内存中为字符流,硬盘上为字节流,硬盘上都是以二进制字节的方式来存的。

  • InputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符。

  • OutputStreamWriter是从字符流到字节流的桥接

  • 可设置字符的编码方式。

  • 在BufferedReader中包装一个InputStreamReader,或在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换器调用。

  • InputStreamReader

    package IO;
    
    import java.io.*;
    
    /**
     * 输入转换流,硬盘中是字节流,将硬盘中的字节以指定编码读入内存中
     * 实现字节流到字符流的转换
     *在简体中文Windows操作系统中,ANSI编码代表GB2312编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 JIS 编码。
     */
    public class InputStreamReaderDemo {
        public static void main(String[] args) throws Exception{
            FileInputStream fis=new FileInputStream("F:\\han.txt");
            InputStreamReader isr=new InputStreamReader(fis,"gb2312");//第二个参数可以指定编码格式,不定为默认UTF-8
            BufferedReader br=new BufferedReader(isr);
            int count=0;
            while((count=br.read())!=-1){
                System.out.print((char) count);
            }
            br.close();
        }
    }
    
    
  • OutputStreamWriter

    package IO;
    
    import java.io.*;
    
    /**
     * 输出转换流:将内存中的字符流按指定格式,以二进制字节的方式写入到硬盘中
     * 实现字符流到字节流的转换
     */
    public class OutputStreamWriterDemo {
        public static void main(String[] args) throws Exception{
            FileOutputStream fos=new FileOutputStream("F:\\sp.txt",true);
            OutputStreamWriter osw =new OutputStreamWriter(fos,"GB2312");
            BufferedWriter bw=new BufferedWriter(osw,2);//通过构造方法来指定缓冲区大小
            for (int i = 0; i < 10; i++) {
                bw.write("韩氏最N");
                bw.newLine();
            }
            bw.flush();
            bw.close();
        }
    }
    

十二、File类

  • 概念:代表物理盘符中的一个文件或者文件夹

  • 方法:

    • createNewFile()//创建一个新文件
    • mkdir()//创建一个新目录
    • delete()//删除文件或空目录
    • exists()//判断File对象是否存在
    • getAbsolutePath()//获取文件的绝对路径
    • getName()//取得名字
    • getParent()//获取文件/目录所在的目录
    • isDirectory()//是否是目录
    • isFile()//是否是文件
    • length()//获取文件的长度
    • listFiles()//列出目录中的所有内容
    • renameTo()//修改文件名为
  • File类操作文件及文件夹

  • package IO.File;
    
    import java.io.File;
    import java.sql.SQLOutput;
    import java.util.Date;
    import java.util.Scanner;
    
    /**
     * 文件类
     * (1)分割符
     * (2)文件操作
     * (3)文件夹操作
     */
    public class FileOperationDemo {
        public static void main(String[] args) throws Exception{
            //separator();
            //fileOperation();
            dirOperation();
        }
        //分割符
        public static void separator(){
            //路径分割符,下面两个属性是一样的,一个是Sting类型,一个是Char类型
            System.out.println(File.pathSeparator);//输出;
            System.out.println(File.pathSeparatorChar);
            //文件分类符
            System.out.println(File.separator);//输出:\
            System.out.println(File.separatorChar);
        }
        //文件操作
        public static void fileOperation() throws Exception{
            //File file=new File("file.txt");//这种方式的路径为当前项目的根路径
            File file=new File("F:\\file.txt");//这种方式为绝对路径
            //创建文件
            if (!file.exists()) {//判断文件是否存在
                boolean status = file.createNewFile();
                System.out.println("创建文件状态:" + status);
            }
            //删除文件
            //第一种删除方式,直接删除
            //System.out.println("文件删除状态:"+file.delete());
            //第二种删除文件的方式,jvm退出时删除
    //        file.deleteOnExit();
            /*Scanner scanner=new Scanner(System.in);
            scanner.next();*/
            //线程休眠5s
    //        Thread.sleep(5000);
            //获取文件信息
            System.out.println("获取绝对路径"+file.getAbsolutePath());
            System.out.println("获取路径"+file.getPath());//构造方法中的路径
            //如果以相对路径进行构造,则返回null
            System.out.println("获取父目录"+file.getParent());
            System.out.println("获取文件名"+file.getName());
            System.out.println("获取文件长度"+file.length());
            //file.lastmodified返回的是long类型的毫秒数
            System.out.println("获取文件创建时间"+new Date(file.lastModified()).toLocaleString());
            //判断
            System.out.println("是否为可写(只读)"+file.canWrite());
            System.out.println("是否为隐藏"+file.isHidden());
            System.out.println("是否为文件"+file.isFile());
        }
        //文件夹操作
        public static void dirOperation() throws Exception{
            //File dir=new File("aaa\\bbb\\ccc");
            File dir=new File("F:\\aaa\\bbb\\ccc");
            System.out.println(dir.toString());
            //创建文件夹
            if (!dir.exists()) {
                //System.out.println("创建结果:" + dir.mkdir());//只能创建单级目录
                System.out.println("创建结果:" + dir.mkdirs());//能创建多级目录
            }
            //删除文件夹
            //方式一,直接删除,删除最后一个文件夹
            //System.out.println("删除结果"+dir.delete());
            //方式二,jvm删除
    //        dir.deleteOnExit();
    //        Thread.sleep(5000);
            //获取文件夹信息
            System.out.println("获取绝对路径"+dir.getAbsolutePath());
            System.out.println("获取路径"+dir.getPath());
            System.out.println("获取文件夹名字"+dir.getName());
            System.out.println("获取父目录"+dir.getParent());
            System.out.println("获取创建时间"+new Date(dir.lastModified()).toLocaleString());
            //判断
            System.out.println("是否为目录"+dir.isDirectory());
            System.out.println("是否为文件"+dir.isFile());
            System.out.println("是否隐藏"+dir.isHidden());
            //遍历
            File dir2=new File("F:\\pdf");
            String[] list = dir2.list();//获取文件夹中的文件名
            System.out.println("---------------------");
            for (String s : list) {
                System.out.println(s);
            }
            System.out.println("--------------------");
            File[] files = dir2.listFiles();
            for (File file : files) {
                System.out.println(file);
            }
        }
    }
    

十三、FileFilter接口

  • 需要重写accept方法

  • 当调用File类中的listFiles()方法时,支持传入FileFilter接口实现类,对获取文件进行过滤,只有满足条件的文件才可以出现在listFiles()的返回值中。

  • package IO.File;
    
    import java.io.File;
    import java.io.FileFilter;
    
    public class FileFilterDemo {
        public static void main(String[] args) {
            File dir=new File("F:\\百度云下载");
            System.out.println(dir.exists());
            File[] zips = dir.listFiles(new FileFilter() {
                @Override
                //底层用的ArrayList
                public boolean accept(File pathname) {
                    if (pathname.getName().endsWith("zip")) {
                        return true;//返回true为过滤出的zip
                    }
                    return false;//返回false不过滤
                }
            });
            for (File zip : zips) {
                System.out.println(zip);
            }
        }
    }
    

十四、用递归对文件及文件夹进行遍历及删除

  • package IO.File;
    
    import java.io.File;
    
    /**
     * 1.递归遍历文件和文件夹
     * 2.递归删除文件和文件夹(只有文件夹中没有文件才能删除文件夹)
     */
    public class FilesRecursionDemo {
        public static void main(String[] args) {
            //listFileTest(new File("F:\\work\\KPI - 副本"));
            listFileDeleteTest(new File("F:\\work\\KPI - 副本"));
        }
        //递归遍历文件和文件夹
        public static void listFileTest(File dir){
            System.out.println(dir.getAbsolutePath());
            File[] files = dir.listFiles();
            if (files!=null&&files.length>0){
                for (File file : files) {
                    if (file.isDirectory()){
                        listFileTest(file);
                    }
                    else{
                        System.out.println(file.getAbsolutePath());
                    }
                }
            }
        }
        //递归删除文件和文件夹
        public static void listFileDeleteTest(File dir){
            File[] files = dir.listFiles();
            if (files!=null&&files.length>0){
                for (File file : files) {
                    if (file.isDirectory()){
                        listFileDeleteTest(file);
                    }
                    else{
                        System.out.println(file.getAbsolutePath()+"删除file"+file.delete());
                    }
                }
                System.out.println(dir.getAbsolutePath()+"删除dir"+dir.delete());
            }
        }
    }
    

十五、Properties类

  • properties是属性集合

  • 特点:

    • 存储属性名和属性值
    • 属性名和属性值都是Sting类型
    • 没有泛型
    • 和流有关
  • package IO.Propeties;
    
    import java.io.*;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    /**
     * Properties是属性集合,是HashTable的子类,HashTable实现了Map接口
     * Properties没有泛型,其类型为String
     * Properties和流有关
     */
    public class PropertiesDemo {
        public static void main(String[] args) throws Exception {
            Properties properties=new Properties();
            //设置属性(添加数据)
            properties.setProperty("username","韩信");
            properties.put("age","20");//和setProperty的作用一样,但为了限定String类型,一般不这样加
            //properties.put("age2",20);
            System.out.println(properties.toString());
            //遍历
            //1.KeySet
            Set<Object> objects = properties.keySet();
            for (Object object : objects) {
                System.out.println(object+"======"+properties.get((String)object));
            }
            //2.entrySet
            Set<Map.Entry<Object, Object>> entries = properties.entrySet();
            for (Map.Entry<Object, Object> entry : entries) {
                System.out.println(entry.getKey()+"===="+entry.getValue());
            }
            //3.stringPropertyNames
            Set<String> set = properties.stringPropertyNames();
            for (String s : set) {
                System.out.println(s+"========"+properties.getProperty(s));//只有String类型的才可以遍历
            }
            //和流有关的操作
            //------------list-------------
            PrintWriter printWriter = new PrintWriter("F:\\print.properties");
            properties.list(printWriter);
            System.out.println("list print OK");
            printWriter.close();
            //------------store-------------
            PrintWriter printWriter2 = new PrintWriter("F:\\print1.properties");
            properties.store(printWriter2,"韩test");
            System.out.println("store print OK");
            printWriter.close();
            //------------load-------------
            Properties properties1=new Properties();
            FileReader fileReader = new FileReader("F:\\print1.properties");
            properties1.load(fileReader);
            System.out.println("load print OK");
            System.out.println(properties1);
            fileReader.close();
            //------------storeToXML-------------
            PrintStream printStream1 = new PrintStream("F:\\test.xml");
            properties.storeToXML(printStream1,"test...时");
            System.out.println("storeToXML ok");
            printStream1.close();
            //------------loadFromXML-------------
            Properties properties2=new Properties();
            FileInputStream fileInputStream = new FileInputStream("F:\\test.xml");
            properties2.loadFromXML(fileInputStream);
            System.out.println("loadFromXML ok");
            System.out.println(properties2);
            printStream1.close();
        }
    }
    

十六、总结

  • 流的概念:

    • 内存与存储设备之间传输数据的通道。
  • 流的分类:

    • 输入流、输出流;
    • 字节流、字符流;
    • 节点流、过滤流
  • 序列化和反序列化:

    • 将对象通过流写入到文件,或将对象通过流读取到内存,必须实现Serializable接口。
  • File对象:

    • 代表物理盘符中的一个文件或文件夹。
posted @ 2022-03-21 09:53  是韩信啊  阅读(28)  评论(0编辑  收藏  举报