Java进阶学习9:【File类、递归、IO流】

  • A+
所属分类:Java Java进阶

01. File类的介绍

/*
    目录(directory): 目录指的就是计算机中的文件夹, 文件夹用来存放文件。
    文件(file): 文件用来存储数据。
    路径(path): 表示计算机中的一个位置,这个位置可以是文件夹,也可以是文件。

    在Java中,有一个类叫做File,这个类可以表示【计算机中的文件或文件夹】
    注意,File这个单词本意是文件的意思,但是在Java中,不仅仅可以表示文件,还可以表示文件夹。

    我们可以通过File类的方法对文件或文件夹进行操作。
 */
public class Demo01File {
    public static void main(String[] args) {

    }
}

02. File的构造方法

/*
    File类的构造方法:
        File(String pathname): 根据一个字符串的路径创建一个File对象。这个路径可以是文件,也可以是文件夹。
        File(String parent, String child): 根据父路径和子路径组合创建一个File对象。
            dg.java文件路径:D:\aaa\b3\dg.java
            dg.java父路径:D:\aaa\b3
            dg.java子路径:dg.java
        File(File parent, String child): 根据父路径和子路径组合创建一个File对象。

    File表示计算机中一个文件或文件夹, 这个文件或文件夹可以是存在的,也可以是不存在的。
 */
public class Demo02FileConstructor {
    public static void main(String[] args) {
        //File(String pathname): 根据一个字符串的路径创建一个File对象
        //在Java中,\是转义字符, 转义字符表示把后面的字符改变含义。
        //如果想要表示一个普通的反斜线, 那么需要写两个\\
        //该file对象表示的是d盘下的aa.txt
        File file = new File("d:\\aa.txt");
        System.out.println(file);

        //File(String parent, String child):根据父路径和子路径组合创建一个File对象。
        //使用该构造方法创建一个File对象,这个file对象表示D:\aa\bb.txt
        File file2 = new File("d:\\aa", "bb.txt");
        System.out.println(file2);

        //File(File parent, String child): 根据父路径和子路径组合创建一个File对象。
        //使用该构造方法创建一个File对象,这个file对象表示D:\aa\bb.txt
        File parent = new File("d:\\aa"); //表示父路径
        File file3 = new File(parent, "bb.txt");
        System.out.println(file3);
    }
}

03. 相对路径和绝对路径

/*
    绝对路径: 是一个非常详细的路径, 绝对路径是从盘符开始的。 比如: D:\aa.txt, E:\bb\hello.java
    相对路径: 是一个简短的路径, 相对路径不是从盘符开始的, 相对路径在idea中指的是当前项目下的内容。
              比如:aa, bb.txt

    区分相对路径和绝对路径只需要看他是不是从盘符开始的。
 */
public class Demo03Path {
    public static void main(String[] args) {
        //指的是当前项目文件夹下的aa.txt
        File file = new File("aa.txt");
    }
}

04. File类的获取的方法

/*
    File类中用于获取的方法
        String getAbsolutePath(): 用于获取File对象所表示的绝对路径。
        String getPath(): 获取File对象所表示的路径。
        String getName(): 获取File对象表示的文件或文件夹的名字。
        long length(): 获取File对象所表示的文件的字节数大小。不能获取文件夹的大小,如果File对象表示的是文件夹,那么调用length方法得到的是一个不确定的结果。

 */
public class Demo04GetMethod {
    public static void main(String[] args) {
        method4();
    }

    /*
        long length(): 获取File对象所表示的文件的字节数大小。
     */
    public static void method4() {
        //创建File对象
        File file = new File("d:\\aa.txt");
        //调用file的length方法获取文件的大小
        long size = file.length();
        System.out.println(size);
    }

    /*
        String getName(): 获取File对象表示的文件或文件夹的名字
     */
    public static void method3() {
        //创建File对象
        //File file = new File("d:\\aa.txt");
        File file = new File("d:\\zz");
        String name = file.getName();
        System.out.println(name);
    }

    /*
        String getPath(): 获取File对象所表示的路径。
        如果在创建File对象的时候构造方法中写的是相对路径,调用getPath得到的就是相对路径
        如果在创建File对象的时候构造方法中写的是绝对路径,调用getPath得到的就是绝对路径
     */
    public static void method2() {
        //创建File对象
        File file = new File("aa.txt");
        //调用getPath方法,获取路径
        String path = file.getPath();
        System.out.println(path);
    }

    /*
        String getAbsolutePath(): 用于获取File对象所表示的绝对路径。
     */
    public static void method() {
        //创建file对象
        //File file = new File("d:\\aa.txt");
        File file = new File("aa.txt");
        //调用getAbsolutePath,获取绝对路径
        String path = file.getAbsolutePath();
        System.out.println(path);
    }
}

05. File类的判断方法

/*
    File类的判断方法:
        boolean exists(): 判断File对象所表示的文件或文件夹是否存在。
        boolean isDirectory(): 判断是否是一个文件夹
        boolean isFile(): 判断是否是一个文件
 */
public class Demo05PanDuanMethod {
    public static void main(String[] args) {
        //创建一个file对象
        File file = new File("D:\\iotest\\zz");
        //调用exists判断该file对象表示的文件或文件夹是否存在
        System.out.println("是否存在:" + file.exists());

        //boolean isDirectory(): 判断是否是一个文件夹
        System.out.println("是否是文件夹:" + file.isDirectory());

        //boolean isFile(): 判断是否是一个文件
        System.out.println("是否是文件:" + file.isFile());
    }
}

06. File类的创建方法

/*
    File类中的创建方法
        boolean createNewFile(): 创建一个文件, 如果文件已存在,那么创建失败。 如果创建成功返回true,否则返回false。
        boolean mkdir(): 创建一个文件夹, 如果文件夹已经存在,那么创建失败。 如果创建成功返回true,否则返回false。
        boolean mkdirs(): 创建一个文件夹, 如果文件夹已经存在,那么创建失败。 如果创建成功返回true,否则返回false。

    mkdir只能创建单级目录, mkdirs可以创建多级目录。
 */
public class Demo06CreateMethod {
    public static void main(String[] args) throws IOException {
        method3();
    }

    /*
        boolean mkdirs(): 创建一个文件夹, 如果文件夹已经存在,那么创建失败
        注意: 如果使用mkdirs创建文件时, 上级目录不存在,那么就会一起创建上级目录。
     */
    public static void method3() {
        //创建File对象
        File file = new File("d:\\iotest111\\bb");
        //调用mkdirs创建文件夹
        boolean flag = file.mkdirs();
        System.out.println(flag);
    }

    /*
        boolean mkdir(): 创建一个文件夹, 如果文件夹已经存在,那么创建失败。
        注意: 如果创建文件时,上级目录不存在,那么会创建失败,但是不会报错。
     */
    public static void method2() {
        //创建File对象
        File file = new File("d:\\iotest\\aa");
        //调用mkdir创建文件将爱
        boolean flag = file.mkdir();
        System.out.println(flag);
    }

    /*
        boolean createNewFile(): 创建一个文件, 如果文件已存在,那么创建失败
        注意: 如果创建文件时,上级目录不存在,那么就会创建失败。并且会抛出异常。
     */
    public static void method() throws IOException {
        //创建File对象
        File file = new File("d:\\iotest\\aa.txt");
        //调用createNewFile,创建该文件
        boolean flag = file.createNewFile();
        //输出
        System.out.println(flag);
    }
}

07. File类的删除方法

/*
    File类中的删除方法
        boolean delete(): 删除File对象所表示的文件或文件夹, 如果删除成功返回true。

    File中的delete方法如果删除的是文件夹,只能删除空文件夹。

    【使用delete方法删除的内容不走回收站】
    【使用delete方法删除的内容不走回收站】
    【使用delete方法删除的内容不走回收站】
    【使用delete方法删除的内容不走回收站】
    【使用delete方法删除的内容不走回收站】

 */
public class Demo07DeleteMethod {
    public static void main(String[] args) {
        //创建File对象
        File file = new File("F:\\pucture");
        //调用file的delete方法删除
        boolean flag = file.delete();
        System.out.println(flag);
    }
}

08. File类的遍历的方法

/*
    用于遍历的方法:
        String[] list(): 获取指定目录下的所有文件和文件夹,并放入到字符串数组中返回。
        (重要)File[] listFiles(): 获取指定目录下所有的文件和文件夹, 并放入到File数组中返回。

    注意:
        1. 如果File对象表示的是一个文件,那么调用listFiles得到的结果是一个null值。
        2. 如果File对象表示的内容在计算机中不存在,那么调用listFiles得到的结果也是一个null值
        3. 如果File对象表示的文件夹中没有任何内容,那么调用listFiles得到的结果是一个空数组。
 */
public class Demo08ListMethod {

    public static void main(String[] args) {
        method3();
    }

    public static void method3() {
        //创建File对象
        File file = new File("d:\\iotest\\bb");
        File[] files = file.listFiles();
        System.out.println(Arrays.toString(files));
    }

    /*
        (重要)File[] listFiles(): 获取指定目录下所有的文件和文件夹, 并放入到File数组中返回。
     */
    public static void method2() {
        //创建File对象
        File file = new File("d:\\aaa");
        //调用listFiles获取当前目录下所有的文件和文件夹
        File[] files = file.listFiles();
        //遍历打印
        for (File f : files) {
            System.out.println(f);
        }
    }

    /*
        String[] list(): 获取指定目录下的所有文件和文件夹,并放入到字符串数组中返回。
     */
    public static void method() {
        //创建一个File对象
        File file = new File("d:\\aaa");
        //调用list方法,获取当前目录下面所有的文件和文件夹
        String[] strArr = file.list();
        //遍历
        for (String s : strArr) {
            System.out.println(s);
        }
    }
}

09. 递归的介绍

/*
    递归就是方法调用方法自己。

    有两种递归调用的方式:
        1. 直接递归: method() -> method()
        2. 间接递归: methodA() -> methodB() -> methodC() -> methodA()

    递归的注意事项:
        1. 递归一定要有出口(结束条件), 如果没有结束条件,会一直调用方法,直到栈内存溢出。
        2. 递归次数不能过多, 不然也会栈内存溢出。
 */
public class Demo01DiGui {
    public static void main(String[] args) {
        //method();
        //methodA();
        printCount(1);
    }

    public static void printCount(int count) {
        //如果count是10000,那么就结束调用
        if(count == 10000) {
            return; //使用return结束方法
        }
        System.out.println(count);
        count++;
        printCount(count);
    }

    public static void methodA() {
        System.out.println("methodA");
        methodB();
    }

    public static void methodB() {
        System.out.println("methodB");
        methodC();
    }

    public static void methodC() {
        System.out.println("methodC");
        methodA();
    }

    public static void method() {
        System.out.println("method方法执行了");
        method();
    }
}

10. 递归求阶乘

/*
    使用递归求5的阶乘
        5! = 5 * 4 * 3 * 2 * 1

    求阶乘的思路:
        5! = 5 * 4 * 3 * 2 * 1
        4! = 4 * 3 * 2 * 1
        3! = 3 * 2 * 1
        2! = 2 * 1
        1! = 1

    递归求阶乘的思路
        5! = 5 * 4!
        4! = 4 * 3!
        3! = 3 * 2!
        2! = 2 * 1!
        1! = 1

    如果是1的阶乘, 结果就是固定值1.
    如果是其他数字的阶乘, 结果是 当前数字 * 当前数字减一的阶乘
 */
public class Demo02DiGuiTest {
    public static void main(String[] args) {
        //调用方法求阶乘
        int result = getJieCheng(5);
        System.out.println(result);
    }

    /*
        定义方法,用来求一个数字的阶乘。
     */
    public static int getJieCheng(int num) {
        //判断,如果num是1,那么1的阶乘结果就是1,就直接返回1
        if(num == 1) {
            return 1;//把1当做结果返回.
        }
        //如果num不是1, 结果是 当前数字 * 当前数字减一的阶乘
        return num * getJieCheng(num - 1);
    }
}

11. 递归求阶乘的流程

参考 Java基础学习17:【File类、递归、字节流】中的图

12. 递归求累加和

/*
    使用递归求1-n的和(某个数字的累加和)
        5的累加和:5 + 4 + 3 + 2 + 1
        4的累加和:4 + 3 + 2 + 1
        3的累加和:3 + 2 + 1
        2的累加和:2 + 1
        1的累加和:1

    递归思想:
        5的累加和:5 + 4的累加和
        4的累加和:4 + 3的累加和
        3的累加和:3 + 2的累加和
        2的累加和:2 + 1的累加和
        1的累加和:1(固定值)
 */
public class Demo03DiGuiTest {
    public static void main(String[] args) {
        //调用getSum,求累加和
        int sum = getSum(5);
        System.out.println(sum);
    }

    /*
        定义方法,求指定数字的累加和
     */
    public static int getSum(int num) {
        //如果num是1,1的累加和结果就是固定值1,那么直接就返回1
        if(num == 1) {
            return 1;
        }
        //如果是其他数字, 累加和是 当前数字 + 当前数字减一的累加和
        return num + getSum(num - 1);
    }
}

13. 递归搜索所有的.java文件

/*
    要求:搜索D:\aaa 目录中的.java 文件(打印d:\aaa中每一个.java文件的绝对路径)

    预热:打印某个文件夹下面的所有的文件.

    如果未知层数, 那么可以使用递归。
 */
public class Demo04PrintDir {
    public static void main(String[] args) {
        //printDir(new File("d:\\明星"));
        printJavaFile(new File("d:\\aaa"));
    }

    //打印目标文件夹下所有java文件的绝对路径。
    public static void printJavaFile(File dir) {
        //获取dir目录中的所有的内容(文件或文件夹)
        File[] files = dir.listFiles();
        //遍历打印这个数组
        for (File thisFile : files) {
            //进行判断,如果遍历到的是一个文件夹, 那么就应该拿到这个文件夹下面的内容打印。
            //如果是一个文件,那么可以直接打印这个文件的名字
            if(thisFile.isDirectory()) {
                //如果条件成立,说明是thisFile是文件夹,那么我们应该获取这个文件夹下的内容打印。
                printJavaFile(thisFile);//应该递归调用自己, 打印自己这个文件夹下面的内容
            } else {
                //如果是文件, 要判断是否是.java文件
                if(thisFile.getName().endsWith(".java")) {//获取遍历到的文件名,判断是否以.java结尾
                    //如果条件成立,说明是.java文件,那么就输出这个文件的绝对路径
                    System.out.println(thisFile.getAbsolutePath());
                }
            }
        }
    }

    /*
        定义一个方法,用来遍历文件夹, 打印这个文件夹下的所有文件名。
        参数表示要遍历的文件夹。
     */
    public static void printDir(File dir) {
        //获取dir目录中的所有的内容(文件或文件夹)
        File[] files = dir.listFiles();
        //遍历打印这个数组
        for (File thisFile : files) {
            //进行判断,如果遍历到的是一个文件夹, 那么就应该拿到这个文件夹下面的内容打印。
            //如果是一个文件,那么可以直接打印这个文件的名字
            if(thisFile.isDirectory()) {
                //如果条件成立,说明是thisFile是文件夹,那么我们应该获取这个文件夹下的内容打印。
                printDir(thisFile);
            } else {
                //否则是一个文件, 那么可以直接打印这个文件的名字
                System.out.println(thisFile.getName());
            }
        }
    }

    /*
        定义方法,用来遍历指定文件夹。
     */
    public static void printDir2(File dir) {
        File[] files2 = dir.listFiles();
        //遍历打印这个File数组
        for (File thisFile2 : files2) {
            //判断如果遍历到的是文件夹,那么就遍历打印这个文件夹中的内容
            //如果遍历到的是文件,那么就直接打印文件名
            if(thisFile2.isDirectory()) {
                //如果条件成立,说明遍历到的是文件夹
                printDir3(thisFile2);
            } else {
                //否则是一个文件
                System.out.println(thisFile2.getName());
            }
        }
    }

    /*
        定义方法,遍历指定的文件夹
     */
    public static void printDir3(File dir) {
        File[] files3 = dir.listFiles();
        //遍历打印files3
        for (File thisFile3 : files3) {
            System.out.println(thisFile3.getName());
        }
    }
}

14. IO流的概述

参考 Java基础学习17:【File类、递归、字节流】中的图

15. 字节输出流向文件中输出一个字节

/*
    OutputStream是字节输出流, 可以将Java程序中的数据写到文件中。
    OutputStream是一个抽象类, 如果要用,需要使用它的子类, 常用的子类FileOutputStream

    FileOutputStream的构造方法:
        FileOutputStream(String name): 参数要传递一个字符串,这个字符串表示要将数据写到哪个文件中。
        FileOutputStream(File file): 参数要传递一个File对象, 该File也表示一个文件。

    FileOutputStream中的其他方法:
        void write(int b): 写入一个字节
        void write(byte[] b): 写入一个字节数组
        void write(byte[] b, int off, int len): 写入字节数组的一部分。 参数off表示从哪个位置开始写, len表示写几个
        void close():释放资源,关闭流。

    字节输出流的使用步骤:
        1. 创建一个FileOutputStream对象, 并在构造方法中指定目的地文件, 表示向这个文件中写数据。
        2. 调用write方法,写数据。
        3. 调用close方法释放资源。

    在Java中,一个字符是占两个字节的。 如果这个字符是ASCII码表上的字符, 那么这个字符在操作系统中是占一个字节的。

    汉字在操作系统中是占多个字节的。
        如果文件采用的是GBK的编码, 那么一个汉字是占两个字节的
        如果文件采用的是UTF-8编码, 那么一个汉字是占三个字节的

    注意: 使用write写一个字节的方法,不能向文件中写中文,因为一个中文占多个字节。
 */
public class Demo01OutputStream {
    public static void main(String[] args) throws IOException {
        //创建一个FileOutputStream对象, 并在构造方法中指定目的地文件, 表示向这个文件中写数据。
        /*
            下面代码做了哪些事情
                1. 创建一个FileOutputStream字节输出流对象
                2. 会调用系统资源, 在D盘下创建aa.txt。 如果文件已经存在,那么会覆盖该文件。
                3. 将这个文件和创建的流对象进行绑定, 以后通过这个流对象操作的就是这个文件了。
         */
        OutputStream os = new FileOutputStream("d:\\aa.txt");
        //调用write方法,写数据。
        //void write(int b): 写入一个字节
        os.write(100); //如果传递数字,会查询ASCII码表, 将对应的字符写到文件中。
        //os.write('a');
        //os.write('中');

        //3. 调用close方法释放资源。
        //如果不调用close方法,那么假如程序不结束,该文件会一直处于被占用的状态
        os.close();

        while(true) {

        }
    }
}

16. 字符串和字节数组的相互转换

/*
    字符串和字节(byte)数组的相互转换

    idea默认的编码是UTF-8, 在UTF-8编码中一个汉字占3个字节

    字符串 -> 字节数组
        使用字符串的getBytes去完成
        byte[] getBytes(): 会使用开发环境的编码方式将字符串转成字节数组

    字节数组 -> 字符串
        使用字符串的构造方法完成
        String(byte[] bytes): 将字节数组转成一个字符串(使用开发环境的编码进行转换)
        String(byte[] bytes, int offset, int length): 将字节数组的一部分转成字符串。 offset表示从哪个位置转,length表示转几个
 */
public class Demo02StringParse {
    public static void main(String[] args) {
        //字符串 -> 字节数组
        String s1 = "abcde";
        byte[] bArr1 = s1.getBytes();
        System.out.println(Arrays.toString(bArr1)); //[97, 98, 99, 100, 101]
        String s2 = "你好";
        byte[] bArr2 = s2.getBytes();
        System.out.println(Arrays.toString(bArr2)); //[-28, -67, -96, -27, -91, -67]
        System.out.println("=====================");
        //字节数组 -> 字符串
        //将bArr1转成一个字符串
        String str1 = new String(bArr1);
        System.out.println(str1);
        //将bArr1的一部分转成字符串
        //从索引为1的位置开始转,转3个
        String str2 = new String(bArr1, 1, 3);
        System.out.println(str2);
    }
}

17. 字节输出流向文件中写一个字节数组

/*
    向文件中写入字节数组:
        void write(byte[] b): 写入一个字节数组
        void write(byte[] b, int off, int len): 写入字节数组的一部分。 参数off表示从哪个位置开始写, len表示写几个
 */
public class Demo03OutputStream {
    public static void main(String[] args) throws IOException {
        //创建FileOutputStream输出流
        OutputStream os = new FileOutputStream("day09\\aa.txt");
        //调用方法,写入字节数组
        //byte[] bArr = "hello".getBytes();
        //os.write(bArr);
        //写汉字
        //os.write("你好".getBytes());

        //写字节数组的一部分
        //表示将hello对应的字节数组的一部分写到文件,从索引为1的位置开始写, 写3个
        os.write("hello".getBytes(), 1, 3);

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

18. 文件的续写

/*
    当创建字节输出流对象,并传递字符串文件的时候, 会创建该文件,并且覆盖原来的文件。
    如果想要在原来文件后面写内容,要使用其他的构造方法创建流
    构造方法:
        FileOutputStream(File file, boolean append):第一个参数表示向哪个文件写数据,第二个参数表示是否续写,如果参数是true表示续写
        FileOutputStream(String name, boolean append) :第一个参数表示向哪个文件写数据,第二个参数表示是否续写,如果参数是true表示续写
 */
public class Demo04Append {
    public static void main(String[] args) throws IOException {
        //创建一个字节输出流对象,用来写数据。
        OutputStream os = new FileOutputStream("day09\\bb.txt", true);//true表示要续写
        //调用write方法写数据
        os.write("床前明月光 ".getBytes());
        //释放资源
        os.close();

    }
}

19. 换行写入

/*
    换行写

    如果要向文件中写入换行,需要使用换行符。
    每种操作系统换行符都不同
        windows: \r\n
        linux: \n
        macOS: \r
 */
public class Demo05WriteLine {
    public static void main(String[] args) throws IOException {
        //创建字节输出流对象
        OutputStream os = new FileOutputStream("day09\\cc.txt");
        //调用write方法写两句诗
        os.write("窗寒西岭千秋雪\r\n".getBytes());
        os.write("门泊东吴万里船".getBytes());
        //释放资源
        os.close();
    }
}
  • 资源分享QQ群
  • weinxin
  • 官方微信公众号
  • weinxin
沙海
TripodCloud:性价比最高的CN2 GIA服务器
美女讲师教你学C语言
C语言郝斌老师教程
C语言项目源码分享

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: