Java进阶-File、递归、IO流

目录

前言

File类概述

File类创建对象

绝对路径和相对路径

File类常用API

判断文件类型、获取文件信息

创建文件、删除文件功能

遍历文件夹

方法递归

递归的形式和特点

递归的算法流程、核心要素

常见案例

经典问题-猴子吃桃问题

非规律化递归案例-文件搜索

非规律化递归案例-啤酒问题

字符集

常见字符集介绍

字符集的编码、解码操作

IO流概述

字节流的使用

文件字节输入流(每次读取一个字节)

文件字节输入流(每次读取一个字节数组)

​编辑

文件字节输入流(一次读完全部字节)

文件字节输出流(写字节数据到文件)

文件拷贝

资源释放的方式

try-catch-finally

try-catch-resource

字符流的使用

文件字符输入流(一次读取一个字符)

文件字符输入流(一次读取一个字符数组)

文件字符输出流


前言

学习路线

File类概述

File类创建对象

代码演示

注意:文件路径有常见的3种不同的写法

绝对路径和相对路径

文件路径也分为绝对路径和相对路径

  • 绝对路径:从盘符开始
  • 相对路径:不带盘符,默认直接到当前工程下的目录寻找文件

File类常用API

判断文件类型、获取文件信息

代码参考

public static void main(String[] args) {
        //1.绝对路径创建一个文件对象
        File f1 = new File("C:\\Users\\pcy\\Desktop\\pic_router.png");
        //a.获取他的绝对路径
        System.out.println(f1.getAbsolutePath());
        //b.获取文件定义的时候使用的路径
        System.out.println(f1.getPath());
        //c.获取文件的名称,带后缀
        System.out.println(f1.getName());
        //d.获取文件的大小:字节个数
        System.out.println(f1.length());
        //e.获取文件的最后修改时间
        long time = f1.lastModified();//时间毫秒值
        //解析时间毫秒值
        System.out.println("最后修改时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time));
        //f.判断是文件还是文件夹
        System.out.println(f1.isFile());//是否是文件
        System.out.println(f1.isDirectory());//是否是文件夹


        File f2 = new File("src\\data.txt");
        //a.获取他的绝对路径
        System.out.println(f2.getAbsolutePath());
        //b.获取文件定义的时候使用的路径
        System.out.println(f2.getPath());
        //c.获取文件的名称,带后缀
        System.out.println(f2.getName());
        //d.获取文件的大小:字节个数
        System.out.println(f2.length());
        //e.获取文件的最后修改时间
        long time2 = f2.lastModified();//时间毫秒值
        //解析时间毫秒值
        System.out.println("最后修改时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time2));
        //f.判断是文件还是文件夹
        System.out.println(f1.isFile());//是否是文件
        System.out.println(f1.isDirectory());//是否是文件夹

        System.out.println("----------------------");
        File f3 = new File("E:/");
        System.out.println(f3.exists());
        System.out.println(f3.isFile());
        System.out.println(f3.isDirectory());
    }

创建文件、删除文件功能

代码参考

    public static void main(String[] args) throws IOException {
        File f = new File("src\\data.txt");
        System.out.println(f.createNewFile());//已经有了,返回false
        //a.创建新文件,创建成功返回true,反之不需要这个,以后文件写出去的时候都会自动创建
        File f1 = new File("src\\data2.txt");//创建成功返回true
        System.out.println(f1.createNewFile());
        //b.mkdir创建一级目录
        File f2 =  new File("src\\aaa");//在src下创建aaa目录
        System.out.println(f2.mkdir());//创建成功
        //c.mkdirs创建多级目录
        File f3 = new File("src\\aaa\\bbb\\ccc");//在src下创建aaa\bbb\ccc三级目录
        System.out.println(f3.mkdirs());//创建成功
        //d.删除文件或空文件夹
        System.out.println(f1.delete());//删除成功,被占用一样可以删除
        //只能删除空文件夹不能删除非空的
        File f4 = new File("src\\aaa\\bbb");
        System.out.println(f4.delete());//删除失败,因为aaa里面有bbb不是空文件夹

    }

遍历文件夹

方法递归

递归的形式和特点

死循环会导致递归方法无限调用自己,无法终止,最后出现栈内存溢出

直接递归

间接递归

递归的算法流程、核心要素

用案例去理解

常见案例

  • 计算1-n的和

经典问题-猴子吃桃问题

非规律化递归案例-文件搜索

非规律化递归案例-啤酒问题

代码参考

public class RecursionDemo06 {
    //定义一个静态的成员变量用于存储可以买的酒数量
    public static int totalNumber;//总数量
    public static int lastBottleNumber;//记录每次剩余的瓶子个数
    public static int lastCoverNumber;//记录每次剩余的盖子个数
    public static void main(String[] args) {
        //1.拿钱买酒
        buy(10);

    }
    public static void buy(int money){
        //2.看可以立马卖多少瓶
        int buyNumber = money/2;//5
        totalNumber += buyNumber;

        //3.把盖子和瓶子换算成钱
        //统计本轮总的盖子数和瓶子数
        int coverNumber = lastCoverNumber + buyNumber;
        int bottleNumber = lastBottleNumber + buyNumber;

        //4.统计可以换算的总金额
        int allMoney = 0;
        if(coverNumber >= 4){
            allMoney += (coverNumber / 4)*2;
        }
        lastCoverNumber =coverNumber % 4;

        if(lastBottleNumber >= 4){
            allMoney += (bottleNumber / 2)*2;
        }
        lastBottleNumber =bottleNumber % 2;

        if(allMoney >= 2){
            buy(allMoney);
        }
    }
}

字符集

常见字符集介绍

字符集的编码、解码操作

代码参考

public class Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //1.编码:把文字转换成字节(使用指定的编码)
        String name = "abc";
        byte[] bytes = name.getBytes("GBK");//指定编码
        System.out.println(bytes.length);
        System.out.println(Arrays.toString(bytes));

        //2.解码
        String rs= new String(bytes);
        System.out.println(rs);
    }
}

IO流概述

字节流的使用

文件字节输入流(每次读取一个字节)

改进

文件字节输入流(每次读取一个字节数组)

注:当第三次读取的时候,因为前两次读完只剩下cd了,读完cd之后第三个位置还是原来第二次读取的c,没被覆盖掉,所以输出就是cdc

解决方案:

改进

出现问题:读取中文会出现乱码

我占了三个字节,一次读取3个字节时,先读abc,再读ab,但是发现不够了,读取我的时候就会出现乱码

文件字节输入流(一次读完全部字节)

 针对上述乱码问题的解决方案:一次读完全部字节

代码参考

文件字节输出流(写字节数据到文件)

代码参考

public static void main(String[] args) throws Exception {
        //1.创建一个文件字节输出流管道与目标文件接通
//        OutputStream os = new FileOutputStream(
//                "E:\\仓库\\advanced-java-learning\\file-io-app\\src\\out04.txt");
        //先清空之前的数据,写新的数据进去
        //如果要追加数据
        OutputStream os = new FileOutputStream(
                "E:\\仓库\\advanced-java-learning\\file-io-app\\src\\out04.txt",true);

        //2.写数据出去
        //a.public void write(int a):写一个字节出去
        os.write('a');
        os.write(98);
//        os.write('徐');//写一个字节时不能写中文的,会乱码噢ab�aabc
        os.write("\r\n".getBytes());//换行
        //b.public void write(byte[] buffer):写一个字节数组出去
        byte[] buffer = {'a',97,98,99};
        os.write(buffer);

        byte[] buffer2 = "我是中国人".getBytes();
        os.write(buffer2);
        os.write("\r\n".getBytes());//换行

        //c.public void write(byte[] buffer int pos,int len):写一个字节数组的一部分出去
        byte[] buffer3 = {'a',97,98,99};
        os.write(buffer,0,3);//从0开始写三个
        os.write("\r\n".getBytes());//换行

        //写数据,必须刷新数据
//        os.flush();//刷新之后可以继续使用流
        os.close();//用完之后必须关闭,释放资源,不然会占用内存,关闭已经包含刷新,关闭之后不可以使用了
    }

文件拷贝

资源释放的方式

try-catch-finally

代码参考

public static void main(String[] args) {
        InputStream is = null;
        OutputStream os = null;
        try {

//            System.out.println(10/0);
            //1.定义一个字节输入流管道与源文件接通
            is = new FileInputStream("D:\\Huawei Share\\Huawei Share\\手机截屏录屏\\SVID_20220304_220736_1.mp4");
            //2.创建字节输出流管道与目标文件接通
            os = new FileOutputStream("D:\\new.mp4");

            //3.定义一个字节数组转移数据
            byte[] buffer =new byte[1024];
            int len;//记录每次读取的字节数
            while((len=is.read(buffer))!= -1){
                os.write(buffer,0,len);
            }
            System.out.println("复制完成了!");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //无论代码是否正常结束,都要最后执行这里
            System.out.println("--------finally--------");
            //4.关闭流
            try {
                if(os!=null) os.close();//一定要判断是否非空,因为有可能在还没有创建流的时候就出问题抛异常了
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(is!=null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

try-catch-resource

//法一
public class TryCatchResourceDemo02 {
    public static void main(String[] args) {
        try (
                //这里面只能放资源对象,用完会自动调用资源对象的close方法关闭资源(即使出现异常)
                //1.定义一个字节输入流管道与源文件接通
                InputStream is = new FileInputStream("D:\\Huawei Share\\Huawei Share\\手机截屏录屏\\SVID_20220304_220736_1.mp4");
                //2.创建字节输出流管道与目标文件接通
                OutputStream os = new FileOutputStream("D:\\new.mp4");
//                int age = 23;//不是资源,报错
                ){

            //3.定义一个字节数组转移数据
            byte[] buffer =new byte[1024];
            int len;//记录每次读取的字节数
            while((len=is.read(buffer))!= -1){
                os.write(buffer,0,len);
            }
            System.out.println("复制完成了!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//法二
public class TryCatchResourceDemo03 {
    public static void main(String[] args) throws Exception {
        //这里面只能放资源对象,用完会自动调用资源对象的close方法关闭资源(即使出现异常)
        //1.定义一个字节输入流管道与源文件接通
        InputStream is = new FileInputStream("D:\\Huawei Share\\Huawei Share\\手机截屏录屏\\SVID_20220304_220736_1.mp4");
        //2.创建字节输出流管道与目标文件接通
        OutputStream os = new FileOutputStream("D:\\new.mp4");
        try (is;os){

            //3.定义一个字节数组转移数据
            byte[] buffer =new byte[1024];
            int len;//记录每次读取的字节数
            while((len=is.read(buffer))!= -1){
                os.write(buffer,0,len);
            }
            System.out.println("复制完成了!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

字符流的使用

文件字符输入流(一次读取一个字符)

文件字符输入流(一次读取一个字符数组)

文件字符输出流

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值