今日学习内容

  • File类
  • 递归
  • 字节流

1 File类

1.1 File类概述和构造方法

  • File类介绍

    • 它是文件和目录路径名的抽象表示
    • 文件和目录是可以通过File封装成对象的
    • 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。将来是要通过具体的操作把这个路径的内容转换为具体存在的
  • File类的构造方法

    方法名说明
    File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
    File(String parent, String child)从父路径名字符串和子路径名字符串创建新的 File实例
    File(File parent, String child)从父抽象路径名和子路径名字符串创建新的 File实例
    • 反斜杠 \ 在字符串中有特殊含义,它是一个转义字符,用于转变原字符的意思。
    • 在路径中使用到的 \ 不是希望它起转义作用,而是起分割作用。

1.2 File类创建功能

  • 方法分类

    方法名说明
    public boolean createNewFile()当文件不存在时,创建文件
    public boolean mkdir()创建单级文件夹
    public boolean mkdirs()创建单级和多级文件夹

1.3 File类判断和获取功能

  • 判断功能

    方法名说明
    public boolean isDirectory()判断是否是文件夹
    public boolean isFile()判断是否是文件
    public boolean exists()判断文件或者文件夹是否存在
    • 在文件和文件夹存在的前提下,isDirectory() 和 isFile() 是互斥的(一个为真,另一个一定为假)
  • 获取功能

    方法名说明
    public String getAbsolutePath()获取绝对路径
    public String getPath()获取路径
    public String getName()获取名称
    public String toString()获取路径,底层调用的就是getPath()
    public String[] list()获取当前文件夹下所有的文件和子文件的名称的数组
    public File[] listFiles()获取当前文件夹下所有的文件和子文件的File对象数组

1.4 File类删除功能

  • 方法分类

    方法名说明
    public boolean delete()删除由此抽象路径名表示的文件或目录
  • 绝对路径和相对路径的区别

    • 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:E:itcastjava.txt
    • 相对路径:必须使用取自其他路径名的信息进行解释。例如:myFile\java.txt

2 递归

2.1 递归

  • 递归的介绍

    • 以编程的角度来看,递归指的是方法定义中调用方法本身的现象
    • 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
    • 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
    • 以后编写的递归的代码,一定要先创建一个方法
  • 递归的注意事项

    • 递归一定要有出口。否则内存溢出
    • 递归虽然有出口,但是出口不能太深,递归的次数不宜过多。否则内存溢出

2.2 递归求阶乘【案例】

  • 案例需求

    ​ 用递归求5的阶乘,并把结果在控制台输出

  • 代码实现

    public class DiGuiDemo01 {
        public static void main(String[] args) {
            //调用方法
            int result = jc(5);
            //输出结果
            System.out.println("5的阶乘是:" + result);
        }
    
        //定义一个方法,用于递归求阶乘,参数为一个int类型的变量
        public static int jc(int n) {
            //在方法内部判断该变量的值是否是1
            if(n == 1) {
                //是:返回1
                return 1;
            } else {
                //不是:返回n*(n-1)!
                return n*jc(n-1);
            }
        }
    }

3 IO流

3.1 IO流概述和分类

  • IO流介绍

    • IO:输入/输出(Input/Output)
    • 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
    • IO流就是用来处理设备间数据传输问题的。常见的应用:文件复制;文件上传;文件下载
  • IO流的分类

    • 按照数据的流向

      • 输入流:读数据
      • 输出流:写数据
    • 按照数据类型来分

      • 字节流

        • 字节输入流
        • 字节输出流
      • 字符流

        • 字符输入流
        • 字符输出流
  • 字节和字符

    • 字节是最小存储的单位,1个字节占8个二进制位
    • 字符是由字节组成,到底由多少个字节组成,要看什么类型的字符

      • 数字或者字母字符:一个字符占一个字节
      • 中文:

        • GBK:2个字节
        • UTF-8:3个字节
  • IO流的使用场景

    • 如果操作的是纯文本文件,优先使用字符流
    • 如果操作的是图片、视频、音频等二进制文件。优先使用字节流
    • 如果不确定文件类型,优先使用字节流。字节流是万能的流
  • IO流的使用注意事项

    • IO流相关的类都是java.io包下的类
    • IO流的操作,每一行代码都有异常,需要处理异常
    • IO流操作完之后,一定要记得释放资源,调用close方法

3.2 字节流写数据

  • 字节流抽象基类

    • InputStream:这个抽象类是表示字节输入流的所有类的超类
    • OutputStream:这个抽象类是表示字节输出流的所有类的超类
    • 子类名特点:子类名称都是以其父类名作为子类名的后缀
  • 字节输出流(抽象类:OutputStream)

    • FileOutputStream(String name):创建文件输出流以指定的名称写入文件
  • 使用字节输出流写数据的步骤

    • 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
    • 调用字节输出流对象的写数据方法
    • 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
  • 构造方法

    方法名说明
    FileOutputStream(String pathname)创建一个向具有指定名称的文件中写入数据的输出文件流
    FileOutputStream(String name, boolean append)创建一个向具有指定 name 的文件中写入数据的输出文件流
    FileOutputStream(File file)创建一个向指定 File 对象表示的文件中写入数据的文件输出流
    FileOutputStream(File file, boolean append)创建一个向指定 File 对象表示的文件中写入数据的文件输出流

3.3 字节流写数据的三种方式

  • 写数据的方法

    方法名说明
    void write(int b)将指定的字节写入此文件输出流,一次写一个字节数据
    void write(byte[] b)将 b.length字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据
    void write(byte[] b, int off, int len)将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流, 一次写一个字节数组的部分数据
    close()释放资源

3.4 字节流写数据的两个小问题

  • 字节流写数据如何实现换行

    • windows:rn
    • linux:n
    • mac:r
  • 字节流写数据如何实现追加写入

    • public FileOutputStream(String name,boolean append)
    • 创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头

3.5 字节流写数据加异常处理

  • 异常处理格式

    • try-catch-finally

      try{
          可能出现异常的代码;
      }catch(异常类名 变量名){
          异常的处理代码;
      }finally{
          执行所有清除操作;
      }
    • finally特点

      • 被finally控制的语句一定会执行,除非JVM退出
  • 示例代码

    public class FileOutputStreamDemo04 {
        public static void main(String[] args) {
            //加入finally来实现释放资源
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream("myByteStream\\fos.txt");
                fos.write("hello".getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

3.6 字节流读数据

  • 字节输入流(抽象类:InputStream)
  • 构造方法

    方法名说明
    FileInputStream(String name)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
    FileInputStream(File file)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
  • 注意事项

    • 只能是文件路径,不能是文件夹路径
    • 文件必须存在,不存在就抛异常
    • 可以写相对路径,也可以写绝对路径
  • 成员方法

    方法名说明
    int read()一次读取一个字节,读取到字节,提升为int返回,如果读到文件末尾,返回-1

3.7 字节流复制文本文件【案例】

  • 案例需求

    ​ 把“E:\itcast\窗里窗外.txt”复制到模块目录下的“窗里窗外.txt”

  • 实现步骤

    • 复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
    • 数据源:

      ​ E:\itcast\窗里窗外.txt --- 读数据 --- InputStream --- FileInputStream

    • 目的地:

      ​ myByteStream\窗里窗外.txt --- 写数据 --- OutputStream --- FileOutputStream

  • 代码实现

    public class CopyTxtDemo {
        public static void main(String[] args) throws IOException {
            //根据数据源创建字节输入流对象
            FileInputStream fis = new FileInputStream("E:\\itcast\\窗里窗外.txt");
            //根据目的地创建字节输出流对象
            FileOutputStream fos = new FileOutputStream("myByteStream\\窗里窗外.txt");
    
            //读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)
            int by;
            while ((by=fis.read())!=-1) {
                fos.write(by);
            }
    
            //释放资源
            fos.close();
            fis.close();
        }
    }

3.8 字节流复制图片【应用】

  • 案例需求

    ​ 把“E:\java\mn.jpg”复制到模块目录下的“mn.jpg”

  • 实现步骤

    • 根据数据源创建字节输入流对象
    • 根据目的地创建字节输出流对象
    • 读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
    • 释放资源
  • 代码实现

    public class CopyJpgDemo {
        public static void main(String[] args) throws IOException {
            //根据数据源创建字节输入流对象
            FileInputStream fis = new FileInputStream("E:\\java\\mn.jpg");
            //根据目的地创建字节输出流对象
            FileOutputStream fos = new FileOutputStream("myByteStream\\mn.jpg");
    
            //读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
            byte[] bys = new byte[1024];
            int len;
            while ((len=fis.read(bys))!=-1) {
                fos.write(bys,0,len);
            }
    
            //释放资源
            fos.close();
            fis.close();
        }
    }