Java基础17 file 递归 IO字节流

一、File

1.文件和目录路径名的抽象表示形式 ==> 可以把文件或者是路径来构建成一个File对象 可以使用其方法
2.绝对路径: 从根盘符开始的路径 就是绝对路径 c:\admin\d.txt
4.相对路径:相对于具体参照物的路径 admin\txt idea 中 大部分使用的使用相对路径 相对于当前的项目
例如 相对路径 F:\IdeaProjects\day16 即添加到项目存储的位置文件夹里
5.File 常用的构造
在这里插入图片描述
File对象相当于一个String ,不过是有格式的,且有专属的方法来对文件进行操作,
构造方法第二个参数是添加子目录,
最后一个名称既可以表示目录,也可以表示文件

package day17;

import java.io.File;

public class Test01 {
    public static void main(String[] args) {
        File f = new File("E:\\toolUtils\\dd\\ff");
        File f1 = new File("E:\\toolUtils\\dd","ff");
        File file = new File("E:\\admin");
        File f2 = new File(file,"1.txt");
        System.out.println(f);
        System.out.println(f1);
        System.out.println(file);
        System.out.println(f2);
    }
}

创建的方法

在这里插入图片描述

删除的方法

在这里插入图片描述

package day17;

import java.io.File;
import java.io.IOException;

public class Test02 {
    public static void main(String[] args) throws IOException {
        File f = new File("4.txt");
        //相对路径 F:\IdeaProjects\day16 即添加到项目存储的位置文件夹里
        //File只是单纯的String,有格式才起作用
        //File f = new File("E:\\admin\\3.java");
        System.out.println(f);
        //调用创建的方法
        System.out.println(f.createNewFile());
        //创建一级目录的文件夹
        File f1 = new File("E:\\admin\\text");
        System.out.println(f1.mkdir());
        //创建多级的文件夹
        File f2 = new File("E:\\axieshun\\text");
        System.out.println(f2.mkdirs());
        //删除文件夹
        System.out.println(f.delete());
        //System.out.println(f);

    }
}

剪切 重命名的方法

在这里插入图片描述
mkdirs()方法根据File对象的路径在电脑中创建文件夹,最后文件夹名为b.txt
createNewFile()方法根据File对象的路径在电脑中创建文件,需要正确的后缀名
创建文件夹时不能有同名文件或文件夹 创建文件时不能有同名文件夹或文件否则创建不了,返回false
两个创建方法返回值都是布尔类型 输出并调用方法 System.out.println(f2.mkdirs());
剪切:不在同一个目录执行的是剪切 重命名的:在同一个目录下是重命名
System.out.println(f.renameTo(f4)); 剪切结果是f文件夹移动到并重命名为f4,其子目录会跟着过来,同电脑操作
delete() ==> 只能够删除文件(可以是有内容的文件)以及空的文件夹

package day17;

import java.io.File;
import java.io.IOException;

public class Test03 {
    public static void main(String[] args) throws IOException {
        File f = new File("E:\\admin\\a");
        f.mkdirs();
        File f1 = new File(f,"d.txt");
        f1.createNewFile();
        File file = new File("E:\\admin01\\b");
        file.mkdirs();//根据File对象的路径在电脑中创建文件夹
        File f2 = new File(file,"b.txt");
        //mkdirs()方法根据File对象的路径在电脑中创建文件夹,最后文件夹名为b.txt
        //f2.mkdirs();
        //f2.delete();
        //createNewFile()方法根据File对象的路径在电脑中创建文件,需要正确的后缀名
        //创建文件夹时不能有同名文件或文件夹 创建文件时不能有同名文件夹或文件否则创建不了,返回false
        //f2.createNewFile();
        //两个创建方法返回值都是布尔类型 输出并调用方法
        System.out.println(f2.mkdirs());
        System.out.println(f2.createNewFile());
        System.out.println(f2.isDirectory());//是否为目录即文件夹
        System.out.println(f2.isFile());//是否为文件
        System.out.println(f2.exists());//是否存在
        //剪切:不在同一个目录执行的是剪切 重命名的:在同一个目录下是重命名
        File f3 = new File(file,"c.txt");
        System.out.println(f2.renameTo(f3));
        File f4 = new File("E:\\admin01\\c");
        System.out.println(f.renameTo(f4));
        //剪切结果是f文件夹移动到并重命名为f4;其子目录会跟着过来,同电脑操作

    }
}

判断的方法

在这里插入图片描述

获取的方法

在这里插入图片描述
这里的长度指大小(byte,kb,mb,gb),文件夹为空所以长度为0

package day17;

import java.io.File;

public class Test04 {
    public static void main(String[] args) {
        File f = new File("E:\\admin\\2.txt");
        System.out.println(f.getAbsolutePath());
        System.out.println(f.getPath());
        System.out.println(f.getName());
        System.out.println(f.getParent());
        System.out.println(f.length());
        /*E:\admin\2.txt
        E:\admin\2.txt
        2.txt
        E:\admin
        0*/
        //文件夹为空所以长度为0

    }
}

过滤的方法(筛选)

在这里插入图片描述
过滤器 是一个匿名类,作为方法参数,重写其方法得到相应功能,如果不重写,相当于所有子目录都返回ture,遍历所有子目录,但不会遍历子子目录,需要递归调用
list返回存储单个文件名称String的数组 listFiles返回存储File对象(相对路径)的数组
目前list 和listFiles返回的打印出来的值都一样

package day17;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;

public class Test05 {
    public static void main(String[] args) {
        File f = new File("E:\\admin\\a");
        //过滤器 是一个匿名类,作为方法参数,重写其方法得到相应功能
        //只遍历指定文件夹的子目录,不会遍历子子目录
        //list返回存储单个文件名称的数组  listFiles返回存储File对象(相对路径)的数组
        //目前list 和listFiles返回的打印出来的值都一样
        String [] nums = f.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                //第一个参数是上一级文件对象
                //第二个参数表示是当前文件的名称
               //返回值 return true 表示存入到数组中 否则不存
                //System.out.println(dir.getName()+"===");
               // System.out.println(name+"----");
                if(name.endsWith("jpg")||name.endsWith("jpeg")
                || name.endsWith("png")){
                    return true;
                }
                return false;
            }
        });
        System.out.println(Arrays.toString(nums));
        File [] files = f.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                if(name.endsWith("jpg") ||
                        name.endsWith("jpeg")||name.endsWith("png")){
                    return true;
                }
                return false;
            }
        });
        for (File f1 : files) {
            System.out.println(f1.getName());
        }

    }
}

二、递归

1.递 传递 归 归还 归一 在开发中就是将大的范围逐渐递归成小的范围
2.递归: 就是方法反复自己调用
3.注意点:
(1)递归中是方法反复自己调用自己 方法中的参数会逐渐变小 朝着不递归的方向去发展
具体使用就是在运算表达式中调用方法
(2) 递归一定注意这个错误 栈内存 溢出
4.数学中的递归

package day17;

public class Test07 {
    public static void main(String[] args) {
        System.out.println(showNum(5));
        System.out.println(showInfo(20));

    }
    //阶乘
    public static int showNum(int num){
        if (num<0){
            return -1;
        }else if(num == 0||num==1){
            return 1;
        }else {
            return num*showNum(num-1);
            //showNum(num)*showNum(num-1); StackOverflowError 栈溢出
            //在运算表达式中调用方法
            //5*showNum(4) 5*4*showNum(3) 5*4*3*showNum(2)
            //5*4*3*2*showNum(1) 5*4*3*2*1

        }
    }
    //前加后等于第三个数 斐波那契数
    public static int showInfo(int num){
        if(num == 1){
            return 1;
        }else if(num ==2){
            return 1;
        }else {
            return showInfo((num-1))+showInfo((num-2));
        }
    }
}

5.递归的内存图
在这里插入图片描述
需求:删除一个目录下的文件以及当前文件
分析 : 1,文件的方法 delete() ==> 只能够删除空的文件夹以及文件
2.使用递归来反复的删除

package day17;

import java.io.File;
import java.io.FilenameFilter;

public class Test08 {
    public static void main(String[] args) {
        deleteAll(new File("e:\\admin"));
    }
    public static void deleteAll(File src){
        File [] files = src.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return true;//无if条件语句,全部都返回ture,
                // 即读取所有子目录,无论是文件还是文件夹,返回File对象,
                // 但依然不会读取子子目录,需要递归,如果是文件夹在调用方法读取
            }
        });
        for (File f:files) {
            //判断是否是目录即文件夹
            if(f.isDirectory()){
                //是文件夹在进行递归
                deleteAll(f);
            }else {
                //不是文件夹就是文件直接删除
                f.delete();
            }
        }
        //最后剩下一个空文件夹即输入File对象的最后一个名称,可以直接删除
        src.delete();
    }
}

需求分析:1.使用递归来进行操作
2.需要判断是否是目录 是目录才进行递归
3.对文件进行过滤 可以使用判断后缀名就可以了

package day17;

import java.io.File;
import java.io.FilenameFilter;

public class Test09 {
    public static void main(String[] args) {
        showImg(new File("e:\\admin01"));
    }

    private static void showImg(File src) {
        if(src!=null){
            if (src.isDirectory()){
                //不传入匿名类重写方法 就相当于返回ture,读取所有子目录
                File[] files = src.listFiles();
                if(files!=null && files.length>0) {
                    for (File file : files) {
                        showImg(file);
                        if(file.getName().endsWith("png")||file.getName().endsWith("jpg")
                        ||file.getName().endsWith("jpeg")){
                            System.out.println(file.getName());
                        }
                    }
                }
            }


        }
    }
}

总结都在代码注释里和加粗重点里,注释已单独提出加粗表示,有几个图比较重要,加粗了标题,多理解多敲

三、IO概念

1.I==>Input 输入 O ==>Output 输出 主要用于设备中的数据进行交互
2.使用场景:文件的copy 文件的上传与下载 微信中的聊天 也需要使用io来进行数据的传输
3.IO流的分类
1.按照流向进行划分: 输入流 与输出流
2.按照类型来进行划分:字节流 字符流
4.输入流与输出流
在这里插入图片描述
4. 字节流: 万物皆字节 字节输入流 读 字节输出流 写
字符流 底层也是使用字节进行操作,只是经过了转换 读写取纯字符的效率会高一点 字符输入流
字符输出流
5. 字节流: 操作字节 以及音频 视频 图片的时候 就使用字节来进行操作
字符流: 用于来操作字符的时候 就使用字符流
在开发中不确定使用使用字节还是字符 一般建议使用字节进行操作
6.io流操作的注意事项
1.所有的流都是使用java.io包的下的类
2.流的操作的时候 会产生异常 需要自行处理 一般用声名异常解决
3.流资源使用之后 一定要关闭资源 流资源比较消耗内存

OutputStream

1.此抽象类是表示输出字节流的所有类的超类 这个类是不能实例化的,需要通过子FileOutputStream使用向上转型实例化
2.常规的一些方法
在这里插入图片描述

FileOutputStream

1.文件输出流是用于将数据写入 File
2.FileOutputStream 用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用
FileWriter
3.常见的构造方法
在这里插入图片描述
构造方法 new FileOutputStream(file,false/ture); 第二个参数是false 则覆盖原来文件内容重新写,第二个参数为ture 则在原文件内容后面添加,不写第二个参数默认为false
4.构造方法三件事
1.实例化FileOutputStream 对象
2.创建一个空的文件
3.将 FileOutputStream 指向这个空的文件

即new 一个FileOutputStream对象时,会创建一个空的文件,同时指向这个文件
5.使用FileOutputStream 步骤
1.实例化FileOutputStream 对象
2.调用其写的方法 writer()
3.关闭流资源
需求:一个一个字节写入到文件中
一次写入多个字节

package day17;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test10 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("e:\\1.txt");
        fos.write(97);
        fos.write(98);
        fos.write(99);
        byte [] bytes= {65,66,67};
        fos.write(bytes);
        fos.write(bytes,0,2);//参数意义,off,即从数组索引开始输出,len,即输出该数组索引后多少位
        //再次运行相当于清空内容重新输出
        fos.close();

    }
}

fos.write(bytes,0,2);参数意义,off,即从数组索引开始输出,len,即输出该数组索引后多少位
一个类中第一次调用写入时会清空重输,第二次以及之后调用写入是添加内容

package day17;

import java.io.FileOutputStream;
import java.io.IOException;

public class Test11 {
    public static void main(String[] args) throws IOException {
        String s= "张三偷偷看小电影";
        String s1 = "李四发现了,一起偷偷看电影";
        FileOutputStream fos = new FileOutputStream("e:\\1.txt");
        //相对路径在 F:\IdeaProjects\day16下
        fos.write(s.getBytes());
        fos.write("\r\n".getBytes());
        fos.write(s1.getBytes());
        fos.close();

    }
}

6.FileOutputStream 写入数据的原理
在这里插入图片描述
java 是不能直接向操作中的文件写入数据,需要jvm来找操作系统,调用操作系统的方法来写入数据
7.记事本打开文件的时候 0-127 范围之内的字节 对应的ascmll表进行转换 其它范围都是使用系统默
认码表进行转换
记事本默认的码表就是GBK

InputStream

1.此抽象类是表示字节输入流的所有类的超类 也是抽象类 不能够实例化,通过子类FileInputStream实例化
2.常用的一些方法
在这里插入图片描述

FileInputStream

1.FileInputStream 从文件系统中的某个文件中获得输入字节 用于来读取文件中的字节
2.FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用
FileReader
3.常用的构造方法

在这里插入图片描述
4.构造两件事
1.实例化 FileInputStream 流对象
2.FileInputStream 指定需要读取的文件
5.使用的步骤
1.实例化 FileInputStream 流对象
2.调用读的方法 read()
3.关闭流资源
代码

package day17;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test12 {
    public static void main(String[] args) throws IOException {
        /*FileOutputStream fos = new FileOutputStream("1.txt");
        byte [] b = {97,97,98,99,66};
        fos.write(b);*/
        FileInputStream fis = new FileInputStream("1.txt");
       /* int len = fis.read();
        System.out.println(len);
        int len1 = fis.read();
        System.out.println(len1);
        int len2 = fis.read();
        System.out.println(len2);
        int len3 = fis.read();
        System.out.println(len3);*/
        //定义一个变量来接受
        int leng =-1;
        while ((leng=fis.read()) !=-1){
            System.out.println((char) leng);
        }
        //只会从未读的一个一个开始读,
        // 如果前面读了一部分,while里的只会接着未读的部分开始读直到读完所有
        fis.close();




    }
}

只会从未读的一个一个开始读,
如果前面读了一部分,while里的只会接着未读的部分开始读直到读完所有

6 读取的原理
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值