JAVA学习打卡第十天——IO流

JAVA学习打卡第十天

学习视频

什么是流

  • 概念内存与存储设备之间传输数据的通道
  • 水借助管道传输;数据借助流传输
  • 流的分类:
    • 按方向【重点】:
      • 输入流:<存储设备>中的内容读入到<内存>中
      • 输出流:将<内存>中的内容写入到<存储设备>中
    • 按单位:
      • 字节流:以字节为单位,可以读写所有数据
      • 字符流:以字符为单位,只能读写文本数据
    • 按功能:
      • 节点流:具有实际传输数据的读写功能
      • 过滤流:在节点流的基础上增强功能

字节流

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

    • InputStream:字节输入流
    • OutputStream:字节输出流
  • 文件字节流

    • FileInputStream:

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

      • 示例

        import java.io.FileInputStream;
        
        public class FileStreamTest_1 {
            public static void main(String[] args) throws Exception{
                //创建一个FileInputStream,并指定文件路径
                FileInputStream fis = new FileInputStream("D:\\javatest.txt");
                //读取文件(单个字节读取)
                System.out.println("==========单个字节读取==========");
                int data = 0;
                while ((data = fis.read()) != -1) {
                    System.out.print((char) data);//--->读出内容为对应的ascill编码,要强制类型转换
                }
                System.out.print("\n执行完毕");
                //关闭
                fis.close();
            }
        }
        

        在这里插入图片描述

        import java.io.FileInputStream;
        
        public class FileStreamTest_2 {
            public static void main(String[] args) throws Exception {
                //创建一个FileInputStream,并指定文件路径
                FileInputStream fis = new FileInputStream("D:\\javatest.txt");
                //多个字节读取
                System.out.println("==========多个字节读取(1)==========");
                byte[] buf = new byte[3];
                int count = fis.read(buf);
                System.out.println(new String(buf));
                System.out.println(count);
                count = fis.read(buf);
                System.out.println(new String(buf));
                System.out.println(count);
                count = fis.read(buf);
                System.out.println(new String(buf, 0, count));
                System.out.println(count);
                //关闭
                fis.close();
            }
        }
        

        在这里插入图片描述

        import java.io.FileInputStream;
        
        public class FileStreamTest_3 {
            public static void main(String[] args) throws Exception{
                FileInputStream fis = new FileInputStream("D:\\javatest.txt");
                System.out.println("==========多个字节读取(2)==========");
                byte[] buf = new byte[3];
                int count = 0;
                while ((count = fis.read(buf)) != -1) {
                    System.out.println(new String(buf, 0, count));
                }
            }
        }
        

        在这里插入图片描述

    • FileOutputStream:

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

      • 示例

        import java.io.FileOutputStream;
        
        public class FileStreamTest_4 {
            public static void main(String[] args) throws Exception{
                //创建文件字节输出流对象
                //FileOutStream会覆盖文件中原来的数据,如不想覆盖,应在文件名后的append赋值为true
                FileOutputStream fos = new FileOutputStream("D:\\javatest_2.txt", true);
                //写入文件
                System.out.println("==========单个传入==========");
                fos.write(97);
                fos.write('b');
                fos.write('c');
                System.out.println("==========多个传入==========");
                String string = "Hello world";
                fos.write(string.getBytes());
                //关闭
                fos.close();
                System.out.println("执行完毕");
            }
        }
        

        在这里插入图片描述

        在这里插入图片描述

  • 字节流复制文件

    • 先读入到内存,再写入到硬盘

    • 示例

      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      
      public class FileStreamTest_5 {
          public static void main(String[] args) throws Exception{
              //创建文件字节输入流
              FileInputStream fis = new FileInputStream("D:\\javatestjpg.jpg");
              //创建文件字节输出流
              FileOutputStream fos = new FileOutputStream("D:\\javatestjpg_2.jpg");
              //一边读一边写
              byte[] buf = new byte[1024];
              int count = 0;
              while ((count = fis.read(buf)) != -1) {
                  fos.write(buf, 0, count);
              }
              //关闭
              fis.close();
              fos.close();
              System.out.println("复制完毕");
          }
      }
      
  • 字节缓冲流

    • 缓冲流:BufferedInputStream/BufferOutputStream

    • 提高IO效率,减少访问磁盘的次数

    • 数据存储在缓冲区中,flush是将缓存区的内容写入文件,也可以直接close

    • 示例(输入):

      import java.io.BufferedInputStream;
      import java.io.FileInputStream;
      
      public class BufferStreamTest_1 {
          public static void main(String[] args) throws Exception{
              //创建字节缓冲输入流
              FileInputStream fis = new FileInputStream("D:javatest_in.txt");
              BufferedInputStream bis = new BufferedInputStream(fis);
              //读取
              int data = 0;
              while((data = bis.read()) != -1) {
                  System.out.print((char) data);
              }
              //关闭--->只需要关闭缓冲流,其内部会自动关闭字节流
              bis.close();
          }
      }
      
    • 示例(输出):

      import java.io.BufferedOutputStream;
      import java.io.FileOutputStream;
      
      public class BufferStreamTest_2 {
          public static void main(String[] args) throws Exception{
              //创建字节缓冲输出流
              FileOutputStream fos = new FileOutputStream("D:\\javatest_out_bufferstream.txt");
              BufferedOutputStream bos = new BufferedOutputStream(fos);
              //写入文件--->内容不超过8k时,都写入缓冲区,虽然文件已经创建,但是没有内容
              for (int i = 0; i < 10; i++) {
                  bos.write("helloworld\r\n".getBytes());
                  bos.flush();//----->将缓冲区内容刷入文件
              }
              //关闭
              bos.close();//----->内部会调用flush方法
          }
      }
      
  • 对象流

    • 对象流:ObjectOutputStream/ObjectInputStream

    • 增强了缓冲区功能

    • 增强了读写8种基本数据类型和字符串功能

    • 增强了读写对象的功能

      • readObject():从流中读取一个对象
      • writeObject():向流中写入一个对象
    • 使用流传输对象的过程称为序列化、反序列化

    • 序列化的类必须实现Serializable接口,该接口没有任何内容,只是一个标记

    • 示例(序列化):

      import java.io.Serializable;
      
      public class Student implements Serializable {
          private String name;
          private int age;
          public Student() {
      
          }
          public Student(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          public String getName() {
              return name;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Student[name:"
                      +this.name + ";age:"
                      + this.age + "]";
          }
      }
      
      import java.io.FileOutputStream;
      import java.io.ObjectOutputStream;
      
      public class ObjectStreamTest_1 {
          public static void main(String[] args) throws Exception{
              //创建对象流
              FileOutputStream fos = new FileOutputStream("D:\\Student_out.bin");
              ObjectOutputStream oos = new ObjectOutputStream(fos);
              //实现序列化(写入操作)
              Student student = new Student("xianyun", 20);
              oos.writeObject(student);
              //关闭
              oos.close();
              System.out.println("序列化完毕");
          }
      }
      
    • 示例(反序列化):

      import java.io.FileInputStream;
      import java.io.ObjectInputStream;
      
      public class ObjectStreamTest_2 {
          public static void main(String[] args) throws Exception{
              //创建对象流
              FileInputStream fis = new FileInputStream("D:\\Student_out.bin");
              ObjectInputStream ois = new ObjectInputStream(fis);
              //读取文件(反序列化)
              Student student = (Student) ois.readObject();
              //关闭
              ois.close();
      
              System.out.println(student.toString());
          }
      }
      
    • 序列化和反序列化注意事项

      • 序列化类必须实现Serializeable接口
      • 序列化类中对象属性要求实现Serializable接口
      • 序列化类需要初始化一个序列化版本号ID,此ID保证序列化的类和反序列化的类是同一个类
      • 使用transient修饰属性,则该属性不能被序列化
      • 静态属性(静态成员)不能序列化
      • 序列化多个对象,可以借助集合实现

编码方式

  • 字符编码
    • ISO-8859-1收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号
    • UTF-8:针对Unicode码表的可变长度字符编码
    • GB2312:简体中文
    • GBK:简体中文、扩充
    • BIG5:台湾、繁体中文
  • 当编码方式与解码方式不一致时,会出现乱码

字符流

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

    • Reader:字符输入流
      • public int read(){}
      • public int read(char[] c){}
      • public int read(char[] b, int off, int len){}
    • Writer:字符输出流
      • public void write(){}
      • public void write(String str){}
      • public void write(char[] c){}
  • 文件字符流

    • FileReader:

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

      • 示例

        import java.io.FileReader;
        
        public class charStreamTest_1 {
            public static void main(String[] args) throws Exception{
                //创建文件字符流
                FileReader fr = new FileReader("D:\\hello.txt");
                //读取
                /*
                System.out.println("一次读取单个字符");
                int data = 0;
                while ((data = fr.read()) != -1) {
                    System.out.println((char) data);
                }
                 */
                System.out.println("通过字符缓冲区");
                char[] c = new char[1024];
                int count = 0;
                while ((count = fr.read(c)) != -1) {
                    System.out.println(new String(c, 0, count));
                }
                //关闭
                fr.close();
            }
        }
        
    • FileWriter:

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

        import java.io.FileWriter;
        
        public class charStreamTest_2 {
            public static void main(String[] args) throws Exception{
                FileWriter fw = new FileWriter("D:\\writer.txt");
                //写入
                for (int i = 0; i < 10; i++) {
                    fw.write("java是世界上最好的语言\n");
                    fw.flush();
                }
                //关闭
                fw.close();
            }
        }
        
    • 字符流复制文件

      import java.io.FileReader;
      import java.io.FileWriter;
      
      public class charStreamTest_3 {
          public static void main(String[] args) throws Exception{
              FileReader fr = new FileReader("D:\\writer.txt");
              FileWriter fw = new FileWriter("D:\\writer_copy.txt");
              char[] buf = new char[1024];
              int count = 0;
              while ((count = fr.read(buf)) != -1) {
                  fw.write(buf, 0, count);
                  fw.flush();
              }
              fr.close();
              fw.close();
          }
      }
      
      • 使用FileReader和FileWriter可以复制文本文件,但不能复制图片或者二进制文件
  • 字符缓冲流

    • 缓冲流:BufferedReader/BufferedWriter

      • 高效读写

      • 支持输入换行符

      • 可一次写一行、读一行

      • 示例(输入)

        import java.io.BufferedReader;
        import java.io.FileReader;
        
        public class BufferStreamTest_1 {
            public static void main(String[] args) throws Exception{
                FileReader fr = new FileReader("D:\\writer.txt");
                BufferedReader br = new BufferedReader(fr);
                /*
                char[] buf = new char[1024];
                int data = 0;
                while ((data = br.read()) != -1) {
                    System.out.println(new String(buf, 0, data));
                }
                 */
                System.out.println("==========一行一行读==========");
                String line = null;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
                
                br.close();
            }
        }
        
      • 示例(输出)

        import java.io.BufferedWriter;
        import java.io.FileWriter;
        
        public class BufferStreamTest_2 {
            public static void main(String[] args) throws Exception{
                FileWriter fr = new FileWriter("D:\\writer_copy_2.txt");
                BufferedWriter bw = new BufferedWriter(fr);
        
                for (int i = 0; i < 10; i++) {
                    bw.write("好好学习,天天向上");
                    bw.newLine();
                    bw.flush();
                }
        
                bw.close();
            }
        }
        
  • 打印流(PrintWriter)

    • 封装了print()/println()方法,支持写入后换行
    • 支持数据原样打印
  • 转换流

    • 桥转换流:InputStreamReader/OutputStreamWriter

    • 可将字节流转换为字符流

    • 可设置字符的编码方式

    • 示例

      import java.io.FileInputStream;
      import java.io.InputStreamReader;
      
      public class InputStream_Reader_test {
          public static void main(String[] args) throws Exception{
              //创建InputStreamReader对象
              FileInputStream fis = new FileInputStream("D:\\writer.txt");
              InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
              //读取文件
              int data = 0;
              while ((data = isr.read()) != -1) {
                  System.out.print((char)data);
              }
              //关闭
              isr.close();
          }
      }
      
      import java.io.FileOutputStream;
      import java.io.OutputStreamWriter;
      
      public class OutputStream_Writer_test {
          public static void main(String[] args) throws Exception{
              FileOutputStream fos = new FileOutputStream("D:\\writer_3.txt");
              OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
              for (int i = 0; i < 10; i++) {
                  osw.write("haohaoxuexi,天天向上\n");
                  osw.flush();
              }
              osw.close();
          }
      }
      

File类

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

  • 方法:

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

    import java.io.File;
    import java.util.Date;
    
    public class FileTest {
        public static void main(String[] args) throws Exception {
            //分隔符
            separator();
            //文件操作
            fileOpe();
    
        }
        public static void separator() {
            System.out.println("路径分隔符" + File.pathSeparator);
            System.out.println("名称分隔符" + File.separator);
        }
        public static void fileOpe() throws Exception {
            //创建文件
            File file = new File("D:\\file.txt");
            System.out.println(file.toString());
            if (!file.exists()) {
                Boolean b = file.createNewFile();
                System.out.println("创建结果:" + b);
            } else {
                System.out.println("文件已存在");
            }
            //删除文件
            /*直接删除
            Boolean b2 = file.delete();
            System.out.println("删除结果:" + b2);
             */
            /*使用JVM退出时删除
            file.deleteOnExit();
            Thread.sleep(5000);//--->休眠5秒。5秒后文件自动删除
             */
            //获取文件信息
            System.out.println("获取文件的绝对路径:" + file.getAbsolutePath());
            System.out.println("获取文件的路径:" + file.getPath());
            System.out.println("获取文件的名称:" + file.getName());
            System.out.println("获取文件的父目录:" + file.getParent());
            System.out.println("获取文件的长度:" + file.length());
            System.out.println("获取文件的创建时间:" + new Date(file.lastModified()));
            //判断
            System.out.println("文件是否可写:" + file.canWrite());
            System.out.println("是否是文件:" + file.isFile());
            System.out.println("文件是否隐藏:" + file.isHidden());
        }
    }
    
  • 示例(文件夹操作)

    import java.io.File;
    import java.util.Date;
    
    public class FolderTest {
        public static void main(String[] args) {
            folderOpe();
        }
    
        public static void folderOpe() {
            //创建文件夹
            File dir = new File("D:\\aaa\\bbb\\ccc");
            System.out.println(dir.toString());
            if (!dir.exists()) {
                //fol.mkdir();//---->只能创建单级目录
                Boolean b1 = dir.mkdirs();//---->能创建多级目录
                System.out.println("创建结果:" + b1);
            } else {
                System.out.println("文件已存在");
            }
            //删除文件夹
            /*
            //直接删除:
            System.out.println("删除结果:" + dir.delete());//--->只删除最底层文件夹,且必须是空文件夹
             */
            /*
            //使用JVM删除
            dir.deleteOnExit();
             */
            //获取文件夹信息
            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()));
            //判断
            System.out.println("是否是文件夹:" + dir.isDirectory());
            System.out.println("是否是隐藏的:" + dir.isHidden());
            //遍历文件夹
            //获取文件夹内容
            System.out.println("==========遍历文件夹==========");
            File dir2 = new File("C:\\Users\\20416\\Desktop\\学习用图");
            String[] files = dir2.list();
            for (String file : files) {
                System.out.println(file);
            }
        }
    }
    
  • FileFilter接口

    • public interface FileFilter

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

    • 示例

      import java.io.File;
      import java.io.FileFilter;
      
      public class FileFilterTest {
          public static void main(String[] args) {
              fileFilterTest();
          }
      
          public static void fileFilterTest() {
              File dir = new File("C:\\Users\\20416\\Desktop\\学习用图");
              System.out.println("==========FileFilter接口的使用");
              File[] files = dir.listFiles(new FileFilter() {
                  @Override
                  public boolean accept(File pathname) {
                      if (pathname.getName().endsWith(".png")) {
                          return true;
                      }
                      return false;
                  }
              });
              for (File file : files) {
                  System.out.println(file.getName());
              }
          }
      }
      
  • 递归遍历和递归删除

集合补充——Properties

  • Properties:属性集合

  • 特点:

    • 存储属性名和属性值
    • 属性名和属性值都是字符串类型
    • 没有泛型
    • 和流有关
  • 示例

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.PrintWriter;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    public class PropertiesTest {
        public static void main(String[] args) throws Exception{
            //创建集合
            System.out.println("==========add==========");
            Properties properties = new Properties();
            //添加数据
            properties.setProperty("username", "张三");
            properties.setProperty("age", "20");
            System.out.println(properties.toString());
            //遍历
            System.out.println("==========keyset==========");
            Set<Object> set = properties.keySet();
            for (Object o : set) {
                System.out.println(o + ":" + properties.get(o));
            }
            System.out.println("==========entrySet==========");
            Set<Map.Entry<Object, Object>> set2 = properties.entrySet();
            for (Map.Entry<Object, Object> ob : set2) {
                System.out.println(ob.getKey() + ":" + ob.getValue());
            }
            System.out.println("==========stringPropertyNames==========");
            Set<String> strings = properties.stringPropertyNames();
            for (String string : strings) {
                System.out.println(string + ":" + properties.get(string));
            }
            //和流有关的方法
            System.out.println("==========list方法==========");
            PrintWriter pw = new PrintWriter("d:\\print.txt");
            properties.list(pw);
            pw.close();
            System.out.println("==========store方法==========");
            FileOutputStream fos = new FileOutputStream("D:\\print.properties");
            properties.store(fos, "注释");
            fos.close();
            System.out.println("==========load方法==========");
            Properties properties2 = new Properties();
            FileInputStream fis = new FileInputStream("D:\\print.properties");
            properties2.load(fis);
            System.out.println(properties2.toString());
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值