10 File、递归、字节流

1、File

  • 目录(directory):文件夹,用来存放文件
  • 文件(file):用来存储数据
  • 路径(path):表示计算机中的一个位置,这个位置也可以是一个文件,也可以是一个文件夹。
  • 在java中,有一个类叫做file,可以表示计算机中的文件或者文件夹。
  • 注意:file这个单词表示的是文件的意思,但是在java中File类不仅可以表示文件,也可以表示文件夹。我们也可以调用File中的方法,对文件夹或者文件进行操作。

File中的构造方法:
File(String pathname): 参数字符串要传递一个文件或文件夹的路径,根据文件或文件夹的路径创建File对象
File(String parent, String child):根据父路径和子路径创建一个File对象。
aa.txt文件的路径是:‪D:\iotest\aa.txt
父路径: ‪D:\iotest
子路径: aa.txt
File(File parent, String child): 根据父路径和子路径组合创建一个File对象。
注意:File表示计算机中的一个文件或文件夹,这个文件或文件夹在计算机中可以是存在的,也可以是不存在的。

  • 绝对路径:从盘符目录开始,是一条完整的路径。
  • 相对路径:是一个简单的路径,相对路径并不是从盘符开始的,在idea中,指的是当前项目下的东西。
  • 区分方式:只看是否从盘符目录开始。
  • File类中的获取方法:
String getAbsolutePath();获取File对象表示文件或者文件夹的绝对路径
String getPath();获取路径
String getName();获取文件或者文件夹的名字
long length();获取File对象所表示的文件的字节数大小,如果File表示的文件夹,则调用length所获得的结果是不确定的。

File中用于判断的方法:

boolean exists():用来判断File对象所表示的文件或者文件夹是否存在
boolean isFile();用来判断File对象表示的是否是文件
boolean isDirectory();用来判断File对象所表示的是否是文件夹

File中创建方法:

boolean createNewFile();创建一个文件,如果文件已经存在,则创建失败
boolean mkdir();创建一个文件夹,如果文件夹已经存在,则创建失败
boolean mkdirs():创建一个文件夹,如果文件夹已经存在,则创建失败,可以创建多级目录。

File删除的功能
boolean delete();删除file对象所表示的文件或者文件夹。
注意:delete方法如果删除文件夹,只能删除空文件夹,如果文件夹中有东西,是无法删除文件的。并且使用delete方法删除文件夹则其内容 是不走回收站的。

File对目录进行遍历的方法 :
String[] list();获取指定目录文件夹中的所有的文件或者文件夹,并放入到一个字符串数组中放回。
File[] listFiles();获取指定目录文件夹中的所有的文件和文件夹,并放入到一个File数组中返回。
注意:如果File对象表示的是一个文件,那么调用listFiles方法得到的是一个null值,如果File对象表示的文件夹不存在,调用listFiles方法得到的是一个null值。

public static void main(String[] args) {      //通过File对目录进行遍历
        method3();
    }

    public static void method3() {
        //创建File对象
        File file = new File("d:\\iotest10");
        //调用listFiles方法
        File[] files = file.listFiles();
        System.out.println(files);
    }

    /*
        (记住)File[] listFiles():获取指定目录(文件夹)中的所有的文件和文件夹,并放入到一个File数组中返回
     */
    public static void method2() {
        //创建File对象
        File file = new File("d:\\iotest");
        //调用listFiles方法,获取指定目录下所有的文件或文件夹
        File[] files = file.listFiles();
        //遍历File数组
        for (File thisFile : files) {
            System.out.println(thisFile);
        }
    }

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

    }

2、递归

递归指的是方法自己调用自己。
直接递归:method()-》method()
间接递归:methodA()-》methodB()-》methodC()

递归的注意事项:
(1)递归一定要有出口(结束条件),否则会栈内存溢出了。
(2)递归次数不能太多,否则也会栈内存溢出。

public static void main(String[] args) {
        //调用方法,求阶乘
        int result = getJieCheng(5);
        System.out.println(result);
    }

    /*
        定义方法,求一个数组的阶乘,并将结果返回。
     */
    public static int getJieCheng(int num) {
        //因为1的阶乘就是固定的值,所以直接返回1
        if (num == 1) {
            return 1;
        }
        //如果求其他数字的阶乘,当前数字 * 当前数字减一的阶乘。
        return num * getJieCheng(num - 1);

    }

File 、递归综合案例

import java.io.File;

/*
    要求:搜索D:\aaa 目录中的.java文件(输出d:\aaa目录中所有.java文件的绝对路径)



    预热:要求遍历文件夹,输出这个文件夹中所有的文件名。
    思路:
        1. 定义方法,用来遍历文件夹。
        2. 获取该文件夹下所有的文件或文件夹,将所有的文件和文件夹放入到一个数组。
        3. 遍历数组,拿到每一个文件或文件夹。
        4. 进行判断,如果遍历到的是一个文件夹,我们应该再继续遍历该文件夹
                    如果遍历到的是一个文件, 那么输出文件名。


    如果想要输出所有.java文件的绝对路径,那么在输出文件名之前可以进行判断,如果是.java结尾的文件,那么才输出。
    如果想要输出绝对路径,调用getAbsolutePath,获取绝对路径并输出。

    应用:如果操作未知层级的东西,可以使用递归
 */
public class Demo04PrintDirTest {
    public static void main(String[] args) {
        //调用printDir方法,遍历文件夹
        //printDir(new File("d:\\iotest"));

        //调用searchJavaFile方法,搜索Java文件
        searchJavaFile(new File("d:\\aaa"));
    }

    /*
        定义方法,用来输出所有.java文件的绝对路径
     */
    public static void searchJavaFile(File dir) {
        //获取该文件夹下所有的文件或文件夹,将所有的文件和文件夹放入到一个数组。
        File[] files = dir.listFiles();
        //遍历数组,拿到每一个文件或文件夹。
        for (File thisFile : files) {
            //thisFile表示每一个文件或文件夹
            //进行判断,如果遍历到的是一个文件夹,我们应该再继续遍历该文件夹,输出该文件夹下所有的.java文件。
            if (thisFile.isDirectory()) {
                //递归调用自己,继续搜索该文件夹下的内容。
                searchJavaFile(thisFile);
            } else {
                //否则拿到的肯定是一个文件, 判断该文件的文件名是否以.java结尾
                if (thisFile.getName().endsWith(".java")) {
                    //如果条件成立,表示该文件是.java文件,那么就输出绝对路径
                    System.out.println(thisFile.getAbsolutePath());
                }
            }
        }
    }


    /*
        定义方法,用来遍历文件夹
        参数dir表示要遍历的文件夹
     */
    public static void printDir(File dir) {
        //获取该文件夹下所有的文件或文件夹,将所有的文件和文件夹放入到一个数组。
        File[] files = dir.listFiles();
        //遍历数组,拿到每一个文件或文件夹。
        for (File thisFile : files) {
            //thisFile表示每一个文件或文件夹
            //进行判断,如果遍历到的是一个文件夹,我们应该再继续遍历该文件夹
            if (thisFile.isDirectory()) {
                //递归调用printDir方法,遍历文件夹
                printDir(thisFile);
            } else {
                //否则拿到的肯定是一个文件, 那么输出文件名。
                System.out.println(thisFile.getName());
            }
        }
    }
}

3、IO流–字节流

  • IO流
    1、input:输入,读。 将硬盘中的数据读取到内存中
    2、output:输出, 写。将内存中的数据写入到内存中
    3、流:数据可以在里面传输。

输入和输出都是依照内存为参照物的。

输入进入到内存中去, 输出是从内存中出去。
IO流:用来传输数据。比如上传,下载,拷贝文件。

  • 从流向上分类:输入流,输出流
  • 从类型上分类:字节流, 字符流
  • 字节流顶层父类:
  •   字节输入流:
    
  •   字节输出流:
    
  • 字符流顶层父 类:
  •      字符输入流:Reader
    
  •      字符输入流:Writer
    

在这里插入图片描述
outputStream:是字节输出流,用来写。可以将java程序中的数据写到文件中去。
outputStream:是所有字节输出流的顶层父类,是一个抽象类,如果需要使用子类,最常用的子类是FileoutputStream

FileOutputStream的构造方法:
FileOutputStream(String name):参数要传递一个字符串类型的文件路径。
FileOutputStream(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、创建字节输出流对象,指定一个目的的文件。
2、调用 write方法,写数据
3、调用close方法,释放资源

 public static void main(String[] args) throws IOException {
        //1. 创建字节输出流对象
        OutputStream os = new FileOutputStream("day10\\aa.txt");
        //2. 调用write方法写数据。
        //void write(byte[] b): 向文件中写一个字节数组
        //byte[] bArr = "hello".getBytes();
        //os.write(bArr);
        //写中文
        //os.write("你好".getBytes());

        //void write(byte[] b, int off, int len):向文件中写入字节数组的一部分
        os.write("abcde".getBytes(), 1, 3);


        //3. 调用close方法关闭流
        os.close();
    }

字符在java中是占两个字节的,但是如果这个字符是ASCII码表上的字符,在计算机中是占一个字节的。
中文在文件中是占多个字节的。
如果文件采用的是GBK的编码,那么一个中文是占两个字节的。
如果文件采用utf8编码,那么一个中文是占3个字节的
我们不能使用write方法写一个字节的方式写入中文,因为一个中文是占用多个字节的。

字节数组和字符串的相互转换:
字符串 ——》字节数组:
Byte[] getBytes();使用平台默认的编码方式将字节数组转化成字符串。
字节数组—》字符串:
要使用字符串的构造方法实现:
String (byte[] bytes);使用平台默认的编码方式将字节数组转化成字符串。
String(byte[] bytes, int offset, int length):使用平台默认的编码方式将字节数组的一部分转成字符串,参数offset表示从哪个位置开始转,参数length表示转几个。
平台默认的编码方式指的是开发工具的idea的编码,idea默认的编码是utf8。

追加写
如果使用之前的构造方法创建字节输出流对象,那么会新建文件覆盖掉原来的文件。
如果不想覆盖原来文件,而是在原来文件的后面继续写内容,可以使用其他构造方法创建字节输出流对象。

构造方法:
FileOutputStream(String name, boolean append):第一个参数表示向哪个文件写数据,第二个参数表示是否续写,如果第二个参数是true,表示要进行续写,就不会覆盖原来的文件了
FileOutputStream(File file, boolean append): 同上

如果要向文件中写换行,那么需要使用换行符。
windows:\r\n
linux: \n
mac: \r

 public static void main(String[] args) throws IOException {
        //创建字节输出流对象
        OutputStream os = new FileOutputStream("day10\\cc.txt");
        //写两句诗
        os.write("床前明月光\r\n".getBytes());
        os.write("疑是地上霜".getBytes());
        //释放资源
        os.close();

    }

猜你喜欢

转载自blog.csdn.net/weixin_45507013/article/details/98978880