IO框架Java

IO流

1.什么是流

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

  • 存储设备<---->内存<--->存储设备

2.流的分类

  • 按方向:

    • 输入流:将存储设备中的内容读取到内存中

    • 输出流:将内存中的内容写入到存储设备中

  • 按单位:

    • 字节流:以字节为单位,可以读写所有数据

    • 字符流:以字符为单位,只能读写文本数据

  • 按功能:

    • 节点流:具有实际传输数据的读写功能

    • 过滤流:在节点流的基础上增强功能

3.字节流

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

    • InputStream:字节输入流

      read();

      read(byte[] b);

      read(byte[] b,int off,int len)

    • OuputStream:字节输出流

      write(int n);

      write(byte[] b);

      write(byte[] b,int off,int len)

  • 字节流的子类

    • FileInputStream:

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

      • 代码

        public class Demo01 {
            public static void main(String[] args) throws IOException {
                //1.创建FileInputStream,并指定文件路径
                FileInputStream fis = new FileInputStream("d:\\sy.txt");
                //2.读取文件
                //fis.read():
                //2.1  单个字节读取(读一个打印一次,执行效率较慢)
        //        int date=0;
        //        while((date=fis.read())!=-1){
        //            System.out.println(date);
        //        }
                //2.2  多个字节读取
                byte[] buffer = new byte[1024];
                int count=0;
                while((count=fis.read(buffer))!=-1){
                    System.out.println(new String(buffer,0,count));
                }
                //3.关闭流
                fis.close();
                System.out.println("读取完毕");
            }
        }

    • FileOutputStream:

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

      • 代码

        public class Demo02 {
            public static void main(String[] args) throws Exception {
                ///1.创建文件字节输出流文件
                FileOutputStream fos = new FileOutputStream("d:\\hh.txt",true);//加true每运行一次就重复写入文件
                //2.写入文件
                String str="hha";
                fos.write(str.getBytes());//获得字符串所对应的字节数组
                //3.关闭流
                fos.close();
                System.out.println("执行完毕");
            }
        }
        ​

  • 字节流复制文件

    • 代码

      ​
      //使用文件字节流实现文件的复制
      public class Demo03 {
          public static void main(String[] args) throws Exception {
              //1.创建文件字节输入流
              FileInputStream fis = new FileInputStream("d:\\hh.jpg");
              //2.创建文件字节输出流
              FileOutputStream fos = new FileOutputStream("d:\\huanghao.jpg");
              //3.一边读,一边写
              byte[] buffer = new byte[1024];
              int count;
              while((count=fis.read(buffer))!=-1){
                  fos.write(buffer,0,count);
              }
              System.out.println("执行完毕");
          }
      }

  • 字节缓冲流

    • 缓冲流:BufferedInputStream/BufferedOutputStream

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

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

      • 代码

        ​
        //使用字节缓冲流读取文件
        public class Demo04 {
            public static void main(String[] args) throws Exception {
                //1.创建文件字节缓冲流
                FileInputStream fis = new FileInputStream("d:\\hh.txt");
                //2.创建字节缓冲流
                BufferedInputStream buf = new BufferedInputStream(fis);
                //3.读取
        //        //3.1  直接缓冲流读取
        //        int date=0;
        //        while((date=buf.read())!=-1){
        //            System.out.println((char)date);//直接打印date是打印ASC码值(转类型成char)
        //        }
                //3.2 创建一个缓冲区
                byte[] buffer = new byte[1024];
                int count=0;//计数器
                while((count=buf.read(buffer))!=-1){
                    System.out.println(new String(buffer,0,count));
                }
        ​
                //4.关闭
                buf.close();
                System.out.println("执行完毕");
            }
        }
        //使用字节缓冲流写入文件
        public class Demo05 {
            public static void main(String[] args) throws Exception {
                //1.创建字节缓冲流
                FileOutputStream fis = new FileOutputStream("d:\\Msshen.txt");
                BufferedOutputStream bos = new BufferedOutputStream(fis);
                //2.写入
                for(int i=0;i<10;++i){
                    bos.write("I  want  you  back\r\n".getBytes());
                    bos.flush();//刷新到内存
                }
                //3.关闭流(内部使用flush方法)
                bos.close();
            }
        }

4.对象流

  • 对象流:ObjectOutputStream/ObjectInputStream

    • 增强了缓冲区功能

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

    • 增强了读写对象的功能:

      • readObject() 从流中读取一个对象

      • writeObject(Object obj) 向流中写入一个对象

  • 使用流传输对象的过程称为序列化、反序列化。

  • 代码

    /*
    1.序列化类必须要实现Serializable接口
    2.序列化类中对象属性也要实现Serializable接口
    3.SerializableUID:版本序列号ID
    4.序列化版本号ID,保证序列化的类与反序列化的类是同一个类
    5.使用transient修饰属性,不能被序列化
    6.静态属性不能被序列化
    7.序列化多个对象,用集合
    ​
     */
    public class Student implements Serializable {//此处注意,序列化类必须要实现序列化的接口
        private static final long SerializableUID=100l;
        String name;
        int age;
    ​
        public Student() {//无参构造
        }
    ​
        public Student(String name, int age) {//有参构造
            this.name = name;
            this.age = age;
        }
        public void setName(String name) {
            this.name = name;
        }
    ​
        public void setAge(int age) {
            this.age = age;
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public int getAge() {
            return age;
        }
    ​
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    ​
    
    
    //使用ObjectOutputStream实现对象的序列化
    public class Demo06 {
        public static void main(String[] args) throws Exception {
            //1.创建对象流
            FileOutputStream fos = new FileOutputStream("D:\\king.bin");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            //2.序列化(写入操作)
    ​
            Student stu = new Student("zhangsan",18);
            Student stu2=new Student("lisi",56);
            ArrayList<Student> list=new ArrayList<>();//集合
            list.add(stu);
            list.add(stu2);
            oos.writeObject(list);
            //关闭流
            oos.close();
            System.out.println("序列化完毕");
        }
    }
    //使用ObjectInputStream实现反序列化(读取重构成对象)
    public class Demo07 {
        public static void main(String[] args) throws Exception {
            //1.创建对象流
            FileInputStream fis = new FileInputStream("d:\\king.bin");
            ObjectInputStream ois = new ObjectInputStream(fis);
            //2.读取
    //        Student  stu = (Student)ois.readObject();
            ArrayList<Student> list=(ArrayList<Student>) ois.readObject();
            System.out.println(list.toString());
            //3.关闭流
            ois.close();
            System.out.println("反序列化完毕");
        }
    }
    ​

5.字符编码

  • UTF-8: 针对Unicode码表的可变长度字符编码

  • GB2312: 简体中文

  • GBK: 简体中文、扩充

  • BIG5: 台湾,繁体中文

  • 当编码方式与解码方式不一致时,会出现乱码

6.字符流

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

    • Reader:字符输入流

      • read()

      • read(char[] c)

      • read(char[] b, int off, int len)

    • Writer:字符输出流

      • write(int n)

      • write(String str)

      • write(char[] c)

  • 文件字符流

    • FileReader:

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

      • 代码

        /使用文件字符流FileReader 实现
        public class Demo01 {
            public static void main(String[] args) throws Exception {
                //1.创建文件字符流
                FileReader fr = new FileReader("D:\\hh.txt");
                //2.读取
                //2.1 单个字符读取
        //        int date=0;
        //        while((date=fr.read())!=-1){
        //            System.out.println((char)date);
        //        }
                //2.2  创建一个缓冲区,多个字符一次读取
                char[] buffer = new char[1024];
                int len=0;
                while((len=fr.read(buffer))!=-1){
                    System.out.println(new String(buffer,0,len));
                }
                //3.关闭流
                fr.close();
                System.out.println("读取完毕");
            }
        }

    • FileWriter:

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

    • 使用FileReader和FileWriter复制文本文件,不能复制图片或二进制文件。

    • 使用字节流复制任意文件。

    • 代码

      //使用FileWriter写入文件
      public class Demo02 {
          public static void main(String[] args) throws Exception {
              //1.创建FileWriter对象
              FileWriter fw = new FileWriter("d:\\hh.txt");
              //2.写入
              for (int i = 0; i < 10; i++) {
                  fw.write("不要离开\r\n");
                  fw.flush();
              }
              //3.关闭流
              fw.close();
              System.out.println("写入文件完毕");
          }
      }
      ​

  • 字符缓冲流

    BufferedReader/BufferedWriter

    • 高效读写

    • 支持输入换行符

    • 可一次写一行,读一行

    • 代码

      //使用字符缓冲流读取文件
      public class Demo03 {
          public static void main(String[] args) throws Exception {
              //1.创建缓冲流
              FileReader fr = new FileReader("d:\\hh.txt");
              BufferedReader br = new BufferedReader(fr);
      ​
              //2.读取
      //        //2.1  第一种方式
      //        char[] buffer = new char[1024];
      //        int len=0;
      //        while((len=br.read(buffer))!=-1){
      //            System.out.println(new String(buffer,0,len));
      //        }
              //2.2 第二种方式,一行一行的读
      ​
              String date=null;
              while((date=br.readLine())!=null){
                  System.out.println(date);
              }
              //3.关闭流
              br.close();
          }
      ​
      }
      ​
      ​
      //使用字符缓冲写入文件
      public class Demo04 {
          public static void main(String[] args) throws Exception {
              //1.创建缓冲流
              FileWriter fw = new FileWriter("d:\\sy.txt");
              BufferedWriter bw = new BufferedWriter(fw);
              //2.写入
              for (int i = 0; i < 10; i++) {
                  bw.write("入目无别人");
                  bw.newLine();//换行(在windows系统中换行是\r\n,在linux系统中是\n)
                  bw.flush();
              }
              //3.关闭
              bw.close();
          }
      }
      ​

  • 打印流

    • PrintWriter:

      • 封装了print()/println()方法,支持写入后换行

      • 支持数据原样打印

      • 例如:数字,布尔类型、double

  • 转换流

    • 桥转换流:InputStreamReader/OuputStreamWriter

      • 可将字节流(硬盘)转换成字符流(内存)

      • 可设置字符的编码方式

      • 代码

        //使用InputStreamReader读取文件  使用指定的编码
        public class Demo05 {
            public static void main(String[] args) throws Exception {
                //1.创建InputStreamReader
                FileInputStream fis = new FileInputStream("d:\\hh.txt");
                InputStreamReader isr = new InputStreamReader(fis,"utf-8");
                //2.读取
                char[] buffer = new char[1024];
                int len=0;
                while((len=isr.read(buffer))!=-1){
                    System.out.println(new String(buffer,0,len));
                }
                //3.关闭
                isr.close();
            }
        }
        ​
        //使用OuputStreamWriter写入文件,使用指定的编码
        public class Demo06 {
            public static void main(String[] args) throws Exception {
                //1.创建OuputStreamWriter
                FileOutputStream fos = new FileOutputStream("d:\\out.txt");
                OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
                //2.写入,以指定的编码
                for (int i = 0; i < 10; i++) {
                    osw.write("人总要跟握不住的东西说再见");
                    osw.flush();
                }
                //3.关闭
                osw.close();
            }
        }

7.File类

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

  • 方法:

    • createNewFile()//创建一个新文件

    • mkdir()//创建一个新目录

    • delete()//删除文件或空目录

    • exists()//判断File对象所代表的对象是否存在

    • 代码

      /*
      File类的操作
      1.分隔符
      2.文件
      3.文件夹
       */
      public class Demo01 {
          public static void main(String[] args) throws Exception {
      //     separator();
              fileOpe();
          }
          //1.分割符
          public static void separator(){
              System.out.println("路径分隔符"+ File.pathSeparator);
              System.out.println("名称分隔符"+File.separator);
          }
          //2.文件操作
          public static void fileOpe() throws Exception {
              //1.创建文件  createFile()
              File file = new File("d:\\file.txt");
              //判断File是否存在
              if(!file.exists()){
                  Boolean b=file.createNewFile();
                  System.out.println("创建结果:"+b);
              }
              //2.删除文件
      //        //2.1 file提供的方法
      //        boolean d = file.delete();
      //        System.out.println("删除结果:"+d);
      //          //2.2  由JVM退出时删除file
      //           file.deleteOnExit();
      //          Thread.sleep(5000);
                //3.文件操作
              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());//以UTF-8方式编码时,一个汉字占三个字节
              System.out.println("文件创建时间:"+new Data(file.lastModified()).toLocalString);
      ​
              //4.判断
              System.out.println("是否可写:"+ file.canWrite());
              System.out.println("是否是文件:"+file.isFile());
              System.out.println("是否隐藏:"+file.isHidden());
          }
          //
      }
      //创建文件夹的操作
      public class Demo02 {
          public static void main(String[] args) throws Exception {
              directroyOpe();
          }
          public static void directroyOpe () throws Exception{
              //1.创建文件夹
              File dir = new File("d:\\aaa\\bbb\\ccc");
      //        dir.mkdir();//只能创建单级文件夹
              if(!dir.exists()){
                  System.out.println("文件夹创建"+dir.mkdirs());//创建多级目录
              }
              //2.删除文件夹
              //2.1直接删(只能删除最底层文件夹,且是空文件夹)
      //        System.out.println("删除结果:"+dir.delete());
              //2.2 由JVM删
      //        System.out.println("删除结果:"+dir.deleteOnExit());
              //3.文件夹操作
              System.out.println("文件夹的绝对路径:"+dir.getAbsolutePath());
              System.out.println("文件夹的路径:"+dir.getPath());
              System.out.println("文件夹的父目录:"+dir.getParent());
              System.out.println("文件夹的名字:"+dir.getName());
              System.out.println("文件夹的创建时间:"+new Date(dir.lastModified()).toLocaleString());
              //4,判断
              //System.out.println("是否可写:"+dir.canWrite());
              System.out.println("文件是否隐藏:"+dir.isHidden());
              System.out.println("文件夹是否是文件夹"+dir.isDirectory());
      ​
              //5.遍历文件夹
              File dir2 = new File("d:\\约拍照片");
              String[] list = dir2.list();
              for (String s : list) {
                  System.out.println("D盘文件:"+s);
              }
              //FileFilter的使用
              File[] files=dir2.listFiles(new FileFilter() {
                  @Override
                  public boolean accept(File pathname) {
                      if (pathname.getName() .endsWith(".jpg")) {
                          return true;
                      }
                      return false;
                  }
              });
              for (File file : files) {
                  System.out.println(file);
              }
          }
      }

  • 两个案例

    public class ListDemo {
        public static void main(String[] args) {
           listDir(new File("d:\\myfiles"));
        }
        //案例1:递归遍历文件夹
        public static void listDir(File dir) {
            File[] files = dir.listFiles();
            System.out.println(dir.getAbsolutePath());
            if(files!=null&&files.length>0){
                for (File file : files) {
                    if (file.isDirectory()){
                        listDir(file);//递归
                    }else{
                        System.out.println(file.getAbsolutePath());
                    }
                }
            }
    ​
        }
        //案例2:递归删除文件夹
        public static void deleteDir(File dir) {
            File[] files = dir.listFiles();
            if(files!=null&&files.length>0){
                for (File file : files) {
                    if (file.isDirectory()) {
                        deleteDir(file);//递归
                    }else{
                        //删除文件
                        System.out.println(file.getAbsolutePath());
                    }
    ​
                }
            }
            System.out.println(dir.getAbsolutePath()+"删除"+dir.delete());
        }
    }

8.FileFilter接口

  • public interface FileFilter

    • boolean accept(File pathname)

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

9.补充:Properties

  • Properties:属性集合

  • 特点:

    • 存储属性名和属性值

    • 属性名和属性值都是字符串类型

    • 没有泛型

    • 和流有关

  • 代码

    //测试Properties
    public class Demo03 {
        public static void main(String[] args) throws IOException {
            //1.创建集合
            Properties properties = new Properties();
            //2.添加数据
            properties.setProperty("username","hh");
            properties.setProperty("age","20");
            System.out.println(properties.toString());
            //3.遍历
            //3.1    keySet
            //3.2    entrySet
            //3.3    stringPropertyNames()
            Set<String> pronames=properties.stringPropertyNames();
            for (String s : pronames) {
                System.out.println(s+"---"+properties.getProperty(s));
    ​
            }
            //4.和流有关的方法
            //list方法
            PrintWriter pw = new PrintWriter("d:\\print.txt");
            properties.list(pw);
            pw.close();
            //2.store方法保存
            FileOutputStream fos = new FileOutputStream("d:\\store.properties");
            properties.store(fos,"注释");
            fos.close();
            //3.load方法加载
            Properties properties2 = new Properties();
            FileInputStream fis = new FileInputStream("d:\\store.properties");
            properties2.load(fis);
            fis.close();
            System.out.println(properties2.toString());
        }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

King Gigi.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值