JavaSE进阶(day09,复习自用)

文章详细介绍了Java中的File类,包括创建File对象、获取文件信息、创建和删除文件以及遍历文件夹的方法。接着,讨论了方法递归的概念、形式、应用和经典案例。此外,文章还涵盖了字符集的基本知识,如ASCII、GBK和Unicode,并演示了字符编码和解码的操作。最后,文章探讨了JavaIO流,包括字节流和字符流的使用,以及文件的复制和资源释放方式。

File类的使用

创建File对象

在这里插入图片描述
在这里插入图片描述
1、File类的作用?
创建对象定位文件,可以删除、获取文件信息等。但是不能读写文件内容。
2、File类构建对象的方式 ?
File file = new File(“文件/文件夹/绝对路径/相对路径”);
3、绝对路径和相对路径是什么样的?
绝对路径是带盘符的。
相对路径是不带盘符的,默认到当前工程下寻找文件。

常用方法:判断文件类型、获取文件信息

在这里插入图片描述

常用方法:创建文件、删除文件功能

在这里插入图片描述创建多级目录使用哪个方法?
public boolean mkdirs()
删除文件需要注意什么?
可以删除文件、空文件夹。
默认不能删除非空文件夹。

常用方法:遍历文件夹

在这里插入图片描述

/**

 目标:File针对目录的遍历
 - public String[] list():
 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
 - public File[] listFiles()(常用):
 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)
 */
public class FileDemo04 {
    public static void main(String[] args) {
        // 1、定位一个目录
        File f1 = new File("D:/resources");
        String[] names = f1.list();
        for (String name : names) {
            System.out.println(name);
        }

        // 2.一级文件对象
        // 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)
        File[] files = f1.listFiles();
        for (File f : files) {
            System.out.println(f.getAbsolutePath());
        }

        // 注意事项
        File dir = new File("D:/resources/ddd");
        File[] files1 = dir.listFiles();
        System.out.println(Arrays.toString(files1));


    }
}

补充知识:方法递归

方法递归的形式

什么是方法递归?
递归做为一种算法在程序设计语言中广泛应用。
方法调用自身的形式称为方法递归( recursion)。
递归的形式
直接递归:方法自己调用自己。
间接递归:方法调用其他方法,其他方法又回调方法自己。
方法递归存在的问题?
递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出现象。

方法递归的应用、执行流程、递归算法的三个核心要素

在这里插入图片描述

/**
 * 目标:递归的算法和执行流程
 */
public class RecursionDemo02 {
    public static void main(String[] args) {
        System.out.println(f(5));

    }

    public static int f(int n){
        if(n == 1){
            return 1;
        }else{
            return f(n-1) * n;
        }
    }
}

方法递归的经典案例

在这里插入图片描述

//目标:1-n求和
public class RecursionDemo03 {
    public static void main(String[] args) {
        System.out.println(f(5));

    }

    public static int f(int n){
        if(n == 1){
            return 1;
        }else{
            return f(n-1) + n;
        }
    }
}

在这里插入图片描述

//目标:猴子吃桃

/**
 * 公式(合理的):f(x) - f(x)/2 - 1 = f(x+1)
 *              2f(x) - f(x) - 2 = 2f(x+1)
 *              f(x)  = 2f(x+1) + 2
 *              求f(1) = ?
 *              终结点f(10) = 1;
 *              递归的方向:合理的
 */
public class RecursionDemo04 {
    public static void main(String[] args) {
        System.out.println(f(1));
        System.out.println(f(2));
        System.out.println(f(3));

    }

    public static int f(int n){
        if(n == 10){
            return 1;
        }else{
            return 2 * f(n + 1) + 2;
        }
    }


}

其他形式的方法递归案例

文件搜索

在这里插入图片描述

/**
 * 目标:去F盘搜索eDiary.exe文件
 */
public class RecursionDemo05 {
    public static void main(String[] args) {
        //2.传入目录 和 文件名称
        searchFile(new File("F:/"),"eDiary.exe");


    }

    /**
     * 1.搜索某个目录下的全部文件,找到我们想要的问题。
     * @param dir 被搜索的源目录
     * @param fileName 被搜索的文件名称
     */
    public static void searchFile(File dir,String fileName){
        //3.判断dir是否是目录
        if(dir!= null && dir.isDirectory()){
            //可以找了
            //4.提取当前目录下的一级对象
            File[] files = dir.listFiles();
            //5.判断是否存在一级文件对象,存在才可以遍历
            if(files!=null && files.length>0){
                for (File file : files) {
                    //6.判断当前遍历的一级文件对象是文件还是目录
                    if(file.isFile()){
                        //7.是不是我们要找的,是就把其路径输出
                        if(file.getName().contains(fileName)){
                            System.out.println("找到了!文件位于:" + file.getAbsolutePath());
                            //启动它
                            try {
                                Runtime r = Runtime.getRuntime();
                                r.exec(file.getAbsolutePath());
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }else{
                        //8.是文件夹,需要继续递归寻找
                        searchFile(file,fileName);
                    }
                }
            }
        }else{
            System.out.println("对不起,当前搜索的不是文件夹");
        }
    }

}

在这里插入图片描述

/**
 * 需求:
 * 啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶,
 * 请问10元钱可以喝多少瓶酒,剩余多少空瓶和盖子。
 * 答案:
 * 15瓶 3盖子 1瓶子
 */
public class RecursionDemo06 {

    //定义一个静态的成员变量用于存储可以买的酒数量
    public static int totalNumber;//总数量
    public static int lastBottleNumber;//记录每次剩余的瓶子个数
    public static int lastCoverNumber;//记录每次剩余的盖子个数

    public static void main(String[] args) {
        //1.拿钱买酒
        buy(10);
        System.out.println("总数:" + totalNumber);
        System.out.println("剩余盖子数:" + lastCoverNumber);
        System.out.println("剩余瓶子数:" + lastBottleNumber);

    }

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

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

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

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

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


}

补充知识:字符集

常见字符集介绍

字符集(Character Set)是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集有:
ASCII字符集
GBK字符集
Unicode(UTF-8)字符集等。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
常见字符集底层字符的编码是什么样的?
英文和数字等在任何国家的字符集中都占1个字节
GBK字符中一个中文字符占2个字节
UTF-8编码中一个中文1般占3个字节
编码前的字符集和解码时的字符集有什么要求?
必须一致,否则会出现字符乱码
英文和数字不会乱码

字符集的编码、解码操作

在这里插入图片描述

/**
 * 目标:学会自己进行文字的编码和解码,为以后可能用到的场景做准备。
 */
public class Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //1.编码:把文字转换成字节(使用指定的编码)
        String name = "abc我爱你中国";
        //byte[] bytes = name.getBytes();//以当前代码默认字符集进行编码(UTF-8)
        byte[] bytes = name.getBytes("GBK");//指定编码
        System.out.println(bytes.length);
        System.out.println(Arrays.toString(bytes));

        //2.解码:把字节转换成对应的中文形式(编码前 和 编码后的字符集必须一致,否则乱码)
        //String rs = new String(bytes);//默认的UTF-8会乱码
        String rs = new String(bytes,"GBK");//默认的UTF-8会乱码,所以用GBK解码
        System.out.println(rs);


    }
}

如何使用程序对字符进行编码?
String类下的方法:
byte[] getBytes​():默认编码
byte[] getBytes​(String charsetName):指定编码
如何使用程序进行解码?
String类的构造器:
String​(byte[] bytes):使用默认编码解码
String​(byte[] bytes, String charsetName)):指定编码解码

IO流:概述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

IO流:字节流

字节输入流:每次读取一个字节

在这里插入图片描述每次读取一个字节存在什么问题?
性能较慢
读取中文字符输出无法避免乱码问题。

字节输入流:每次读取一个字节数组

在这里插入图片描述

字节输入流:读取文件的全部字节

在这里插入图片描述

字节输出流:写字节数据到文件

在这里插入图片描述
在这里插入图片描述

文件拷贝

在这里插入图片描述

/**
 * 目标:学会使用字节流完成文件的复制(支持一切文件类型的复制)
 */
public class CopyDemo05 {
    public static void main(String[] args) {
        try {
            //1.创建一个字节输入流管道与原视频接通
            InputStream is = new FileInputStream("D:\\course\\学士服.mp4");

            //2.创建一个字节输出流管道与目标文件接通
            OutputStream os = new FileOutputStream("D:/course/new.mp4");

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


            //4.关闭流
            os.close();
            is.close();

//            os.write(is.readAllBytes());


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

IO流:资源释放的方式

try-catch-finally

在这里插入图片描述

try-with-resource

在这里插入图片描述在这里插入图片描述

字节流

字符输入流- 一次读取一个字符

在这里插入图片描述

字符输入流- 一次读取一个字符数组

在这里插入图片描述

/**
 目标:字符输入流的使用-按照字符数组读取。

 IO流的体系:
 字节流                                       字符流
 字节输入流           字节输出流               字符输入流       字符输出流
 InputStream         OutputStream           Reader         Writer     (抽象类)
 FileInputStream     FileOutputStream       FileReader     FileWriter (实现类)

 c.FileReader:文件字符输入流。
 -- 作用:以内存为基准,把磁盘文件的数据以字符的形式读入到内存。
 简单来说,读取文本文件内容到内存中去。
 -- 构造器:
 public FileReader(File file):创建一个字符输入流与源文件对象接通。
 public FileReader(String filePath):创建一个字符输入流与源文件路径接通。
 -- 方法:
 public int read(): 读取一个字符的编号返回! 读取完毕返回-1
 public int read(char[] buffer):读取一个字符数组,
 读取多少个字符就返回多少个数量,读取完毕返回-1
 小结:
 字符流按照字符数组循环读取数据,可以解决中文读取输出乱码的问题,而且性能也较好!!
 */
public class FileReaderDemo02 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个文件字符输入流与源文件接通
        Reader fr = new FileReader("day09-file-io-app/src/data07.txt");

        //2.用循环,每次读取一个字符数组的数据 1024+1024+8
        char[] buffer = new char[1024];//1k字符
        int len;
        while((len = fr.read(buffer))!=-1){
            String rs = new String(buffer,0,len);
            System.out.print(rs);
        }
    }
}

字符输出流

在这里插入图片描述
在这里插入图片描述

**
     目标:字符输出流的使用。

     IO流的体系:
            字节流                                   字符流
     字节输入流           字节输出流               字符输入流       字符输出流
     InputStream         OutputStream           Reader         Writer     (抽象类)
     FileInputStream     FileOutputStream       FileReader     FileWriter (实现类)

     d.FileWriter文件字符输出流的使用。
        -- 作用:以内存为基准,把内存中的数据按照字符的形式写出到磁盘文件中去。
            简单来说,就是把内存的数据以字符写出到文件中去。
        -- 构造器:
           public FileWriter(File file):创建一个字符输出流管道通向目标文件对象。
           public FileWriter(String filePath):创建一个字符输出流管道通向目标文件路径。
           public FileWriter(File file,boolean append):创建一个追加数据的字符输出流管道通向目标文件对象。
           public FileWriter(String filePath,boolean append):创建一个追加数据的字符输出流管道通向目标文件路径。
        -- 方法:
             a.public void write(int c):写一个字符出去
             b.public void write(String c)写一个字符串出去:
             c.public void write(char[] buffer):写一个字符数组出去
             d.public void write(String c ,int pos ,int len):写字符串的一部分出去
             e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
     小结:
        字符输出流可以写字符数据出去,总共有5个方法写字符。
        覆盖管道:
             Writer fw = new FileWriter("Day10Demo/src/dlei03.txt"); // 覆盖数据管道
        追加数据管道:
             Writer fw = new FileWriter("Day10Demo/src/dlei03.txt",true); // 追加数据管道
        换行:
             fw.write("\r\n"); // 换行
        结论:读写字符文件数据建议使用字符流。复制文件建议使用字节流。
 */
public class FileWriterDemo03 {
    public static void main(String[] args) throws Exception {
        // 1、创建一个字符输出流管道与目标文件接通
        //Writer fw = new FileWriter("day09-file-io-app/src/out08.txt");//覆盖管道,每次启动都会清空文件之前的数据
        Writer fw = new FileWriter("day09-file-io-app/src/out08.txt",true);//追加


//      a.public void write(int c):写一个字符出去
      fw.write(98);
      fw.write('a');
      fw.write('徐');//不会出问题了
      fw.write("\r\n");//换行


//       b.public void write(String c)写一个字符串出去
        fw.write("abc我是中国人");
        fw.write("\r\n");//换行



//       c.public void write(char[] buffer):写一个字符数组出去
        char[] chars = "abc我是中国人".toCharArray();
        fw.write(chars);
        fw.write("\r\n");//换行




//       d.public void write(String c ,int pos ,int len):写字符串的一部分出去
        fw.write("abc我是中国人",0,5);
        fw.write("\r\n");//换行



//       e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
        fw.write(chars,3,5);
        fw.write("\r\n");//换行


//        fw.flush();//刷新后流可以继续使用
        fw.close();//关闭包含刷新,关闭后流不能使用

    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值