黑马Java—第17讲File&递归&字节流

121 阅读12分钟

❤️持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

🎨 个人介绍

👉大家好,我是:旺仔不是程序员

👉认真分享技术,记录学习过程的点滴,如果我的分享能为你带来帮助,请支持我奥🍻

👉你的支持,是我每天更新的动力。

👉赞点:👍 留言:✍ 收藏:⭐

👉个人格言:想法一步一步的落实,才是你我前进最佳选择。

1. file 类

1.1 File类的概述和构造方法

1 )File 类介绍

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

2 )File 类的构造方法

方法名说明
File(String pathname)通过将给定的路径名字符串转换为抽象路径名来创建新的 File 实例
File(String parent,String child)从父路径名字符串和子路径名字符串创建新的 File 实例
File (File parent,String child)从父抽象路径名和字路径名字符串创建新的 File 实例

3 )代码实例

public static void main(String[] args) {
    // 通过将给定的路径名字符串转换为抽象路径名来创建新的 File 实例
    File f1 = new File("E:\BackEndLearning\work\Test1\java.txt");
    System.out.println(f1);
​
    //从父路径名字符串和子路径名字符串创建新的 File 实例
    File f2 = new File("E:\BackEndLearning\work\Test1","java.txt");
    System.out.println(f2);
​
    //从父抽象路径名和字路径名字符串创建新的 File 实例
    File f3 = new File("E:\BackEndLearning\work\Test1");
    File f4 = new File(f3,"java.txt");
    System.out.println(f4);
}

1.2 File 类创建功能

1 )方法分类

方法名说明
public boolean createNewFile()当具有名称的文件不存在时,创建一个由该抽象类路径名命名的新空文件
public boolean mkdir()创建由此抽象路径命名的目录
public boolean mkdirs()创建由此路径名命名的目录,包括任何必须但不存在的父目录

2 )代码实例

public static void main(String[] args) throws IOException {
    //创建文件夹
    File f1 = new File("E:\BackEndLearning\work\Test1\java.txt");
    System.out.println(f1.createNewFile());
    System.out.println("---------------");
​
    //创建单个目录,,如果没有前边的 itcast目录,单个的创建单个目录会创建失败 返回 false
    File f2 = new File("E:\itcast\JavaSE");
    System.out.println(f2.mkdir());
    System.out.println("---------------");
​
    // 创建多级目录
    File f3 = new File("E:\itcast\JavaWEB\HTML");
    System.out.println(f3.mkdirs());
}

1.3 File 的创建和获取功能

1 )判断功能

方法名说明
public boolean isDirectory()测试此抽象路径名表示的File是否为目录
public boolean isFile()测试此抽象类路径名表示的File是否为文件
public boolean exists()测试此抽象类路径名表示的File是否存在

2 )获取功能

方法名说明
public String getAbsolutePath()返回此抽象路径名的绝对路径名 字符串
public String getPath()将此抽象路径名转换为路径名 字符串
public String getName()返回由此抽象路径名表示的文件或目录的名称
public String[] list()返回此抽象路径名表示的目录的文件和目录的名称字符串数组
public File[] listFiles()返回此抽象路径名表示的目录中文件和目录的File对象数组

3 )代码实例

public static void main(String[] args) {
    //创建一个File类对象
    File f = new File("E:\BackEndLearning\work\Test1\java.txt");
​
    //:测试此抽象路径名表示的File是否为目录
    System.out.println(f.isDirectory());
​
    //测试此抽象路径名表示的File是否为文件
    System.out.println(f.isFile());
​
    //测试此抽象路径名表示的File是否存在
    System.out.println(f.exists());
​
    //返回此抽象路径名的绝对路径名字符串
    System.out.println(f.getAbsolutePath());
​
    //:将此抽象路径名转换为路径名字符串
    System.out.println(f.getPath());
​
    //返回由此抽象路径名表示的文件或目录的名称
    System.out.println(f.getName());
    System.out.println("--------");
​
    //返回此抽象路径名表示的目录中的文件和目录的名称字符串数 组
    File f1  = new File("E:\itcast");
    String[] strArray = f1.list();
    for (String str : strArray) {
        System.out.println(str);
    }
    System.out.println("-------------");
​
    //返回此抽象路径名表示的目录中文件和目录的File对象数组
    File[] files = f1.listFiles();
    for (File file : files) {
        if (file.exists()) {
            System.out.println(file.getName());
        }
    }
}

1.4 File 类删除功能

1 )方法介绍

方法名说明
public boolean delete()删除由此抽象路径名表示的文件或目录

2 )代码实例

public static void main(String[] args) throws IOException {
    //在当前模块目录下创建java.txt文件
    File f1 = new File("E:\BackEndLearning\work\Test1\java.txt");
    System.out.println(f1.createNewFile());
​
    //:删除当前模块目录下的java.txt文件
    System.out.println(f1.delete());
    System.out.println("------------");
​
    // 在当前模块目录下创建 itcast 目录
    File f2 = new File("E:\BackEndLearning\work\Test1\itcast");
    System.out.println(f2.mkdirs());
​
    // :删除当前模块目录下的itcast目录
    System.out.println(f2.delete());
    System.out.println();
​
    //在当前模块下创建一个目录itcast,然后在该目录下创建一个文件java.txt
    File f3 = new File("E:\BackEndLearning\work\Test1\itcast");
    System.out.println(f3.mkdirs());
​
    File f4 = new File("E:\BackEndLearning\work\Test1\itcast\java.txt");
    System.out.println(f4.createNewFile());
​
    // :删除当前模块下的目录itcast
    System.out.println(f4.delete());
    System.out.println(f3.delete());
​
}

3 )绝对路径和相对路径的区别

  1. 绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。
  2. 相对路径:必须使用取自其他路径名 的信息进行解释

2. 递归

2.1 递归

1 )递归的介绍

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

2 )递归基本使用

public static void main(String[] args) {
    //不死神兔的案例
    int[] arr = new int[20];
​
    arr[0] = 1;
    arr[1] = 1;
​
    for (int i = 2; i < arr.length;i++){
        arr[i] = arr[i-1] + arr[i -2];
    }
    System.out.println(arr[19]);
    System.out.println(f(20));
}
​
private static int f(int n) {
    if(n==1 || n==2) {
        return 1;
    }else {
        int i = f(n - 1) + f(n - 2);
        return i;
    }
}

3 )递归的注意事项

  1. 递归一定要有出口。否则内存溢出
  2. 递归虽然有出口,但是递归的次数也不易过多。否则内存溢出

2.2 递归求阶乘

1 )案例需求

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

2 )代码实现

public static void main(String[] args) {
    //调用方法
    int number = factorial(5);
    System.out.println(number);
}
​
private static int factorial(int n) {
    if (n == 1) {
        return 1;
    }else {
        return n*factorial(n-1);
    }
}

2.3 递归遍历目录

1 )案例需求

  1. 给定一个路径,通过递归遍历该目录下所有内容,并把所有文件的绝对路径输出在控制台

2 )代码实现

public static void main(String[] args) {
    //根据路径创建一个对象
    File scrFile = new File("E:\BackEndLearning\work\StudentManagementSystem");
​
    getAllFilePath(scrFile);
}
​
private static void getAllFilePath(File scrFile) {
    //获取给定的File 目录下所有的文件或目录的File数组
    File[] fileArray = scrFile.listFiles();
    if (fileArray != null) {
        for (File file : fileArray) {
            // 判断该 File 对象是否为目录
            if(file.isDirectory()) {
                getAllFilePath(file);
            } else {
                System.out.println(file.getAbsolutePath());
            }
        }
    }
}

3. IO 流

3.1 IO 流的概述和分类

1 )IO流的介绍

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

2 )IO流的分类

  1. 按照数据的流向

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

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

3 )IO流的使用场景

  1. 如果操作的是纯文本文件,优先使用字符流
  2. 如果操作的是图片、视频、音频等二进制文件。优先使用字节流
  3. 如果不确定文件类型,优先使用字节流。字节流是万能流

3.2 字节流写数据

1 )字节流抽象基类

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

2 )字节输出流

  1. FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件

3 )使用字节输出流写数据的步骤

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

4 )实例代码

public static void main(String[] args) throws IOException {
    //创建字节输出流对象
    FileOutputStream out = new FileOutputStream("E:\BackEndLearning\work\Test1\fox.txt");
​
    //向文件中写入数据
    out.write(97);
​
    //关闭资源
    out.close();
}

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

1 )写数据的方法分类

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

2 )代码实例

 public static void main(String[] args) throws IOException {
     FileOutputStream out = new FileOutputStream("E:\BackEndLearning\work\Test1\fox.txt");

     //:创建文件输出流以写入由指定的 File对象表示的文件
     File f1 = new File("E:\BackEndLearning\work\Test1\fox.txt");
     FileOutputStream fos2 = new FileOutputStream(f1);

     // 将指定的字节写入此文件输出流

     fos2.write(97);
     fos2.write(98);
     fos2.write(99);
     fos2.write(100);

     //将 b.length字节从指定的字节数组写入此文件输出流
     byte[] bys = {97,98,99,100};

     ///byte[] getBytes():返回字符串对应的字节数组
     byte[] bys1 = "adfjkalfg\r\n".getBytes();


     fos2.write(bys);
     fos2.write(bys1);

     //void write(byte[] b, int off, int len):将 len字节从指定的字节数组开始,从 偏移量off开始写入此文件输出流
     fos2.write(bys1,1,4);

     fos2.close();
 }

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

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

  1. windows : \r\n
  2. linux: \n
  3. mac : \r

2 )字节流写数据如何实现追加写入

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

3 )代码实例

public static void main(String[] args) throws IOException {
    //创建字节输出流对象
    FileOutputStream out = new FileOutputStream("E:\BackEndLearning\work\Test1\fox.txt",true);

    // 写数据
    for (int i = 0; i <10 ;i++) {
        out.write("hello".getBytes());
        out.write("\r\n".getBytes());
    }

    //释放资源
    out.close();
}

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

1 )异常处理格式

  1. try-catch-finally
try {
    可能出现异常的代码;
}catch(异常类名 变量名) {
    异常处理代码;
}finally {
    执行所有清楚操作;
}
  1. finally 特点
  2. 被fianlly控制的语句一定会被执行,除非JVM退出

2 )代码实例

public static void main(String[] args) {
    //加入finally来实现释放资源
    FileOutputStream out = null;
    try {
        out = new FileOutputStream("E:\BackEndLearning\work\Test1\fox.txt");
        out.write("hello".getBytes(StandardCharsets.UTF_8));
    }catch(IOException e){
        e.printStackTrace();
    }finally {
        if (out != null) {
            try {
                out.close();
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.6 字节流读数据

1 )字节输入流

  1. FileinputStream(String name) : 通过打开与实际文件的连接来创建一个FileinputStream,该文件系统中的路径名 name 命名

2 )字节输入流读取数据的步骤

  1. 创建字节输入流对象
  2. 调用字节输入流对象的读数据方法
  3. 释放资源
public static void main(String[] args) throws IOException {
    //创建字节输入流对象
    FileInputStream in = new FileInputStream("E:\BackEndLearning\work\Test1\fox.txt");

    int by;

    while((by=in.read()) != -1) {
        System.out.println((char)by);
    }

    //释放资源
    in.close();
}

3.7 用字节流复制文本文件

1 )案例需求

  1. 把C:\Users\86131\Desktop\1-27\1-27\JavaSE讲义10-Java面向对象封装与继承.pdf复制到E:\itCast\JavaSE讲义10-Java面向对象封装与继承.pdf

2 )实现步骤

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

  2. 数据源:

    • C:\Users\86131\Desktop\1-27\1-27\JavaSE讲义10-Java面向对象封装与继承.pdf--- 读数据 --- InputStream--- FileInputStream
  3. 目的地:

    • E:\itcast\JavaSE讲义10-Java面向对象封装与继承.pdf --- 写数据 --- OutputStream --- FileOutputStream

3 )代码实现

public static void main(String[] args) throws IOException {
    //根据数据源创建字节输入流对象
    FileInputStream in = new FileInputStream("C:\Users\86131\Desktop\1-27\1-27\JavaSE讲义10-Java面向对象封装与继承.pdf");
    //根据目的地创建字节输出流对象
    FileOutputStream out = new FileOutputStream("E:\itCast\JavaSE讲义10-Java面向对象封装与继承.pdf");


    int by = -1;
    //读写数据,复制文本文件(一次读取一个字节,一次写入一个字节)
    while((by=in.read()) !=-1) {
        out.write(by);
    }

    //释放资源
    in.close();
    out.close();
}

3.8 字节流读数据

1 )一次读一个字节数组的方法

  1. public int read(byte[] b) : 从输入流读取最多b.length个字节的数据
  2. 返回的是读入缓冲区的总字节数,也就是实际的读取字节数

2 )代码实例

public static void main(String[] args) throws IOException {
    //创建字节输入流对象
    FileInputStream in = new FileInputStream("E:\BackEndLearning\work\Test1\fox.txt");

    byte[] bys = new byte[1024];
    int len;
    while ((len = in.read(bys))!=-1) {
        System.out.println(new String(bys,0,len));
    }

    //释放资源
    in.close();
}

3.9 字节流复制图片

1 )案例需求

  1. 把C:\Users\86131\Desktop\新建文件夹\1.jpg 复制到 E:\itCast\1.jpg

2 )实现步骤

  1. 根据数据源创建字节输入流对象
  2. 根据目的地创建字节输出流对象
  3. 读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
  4. 释放资源

3 )代码实现

public static void main(String[] args) throws IOException {
    // 根据数据源创建字节输入流
    FileInputStream in = new FileInputStream("C:\Users\86131\Desktop\新建文件夹\1.jpg");
    // 根据目的地创建字节输出流
    FileOutputStream out = new FileOutputStream("E:\itCast\1.jpg");

    //读写数据,复制图片(一次读取一个字节数组,一次写入一个字节数组)
    byte [] bys = new byte[1024];
    int len;
    while((len=in.read(by   s))!=-1) {
        out.write(bys,0,len);
    }

    //释放资源
    in.close();
    out.close();
}

🎈看完了不妨给我点个赞吧,👉你的支持,是我每天更新的动力...