1、File类的使用
(1)创建File对象
File对象可以定位文件和文件夹
File封装的对象仅仅是一个路径名,这个路径可以是存在的,也可以是不存在的
绝对路径:从盘符开始
相对路径:不带盘符,默认直接到当前工程下的目录寻找文件。
(2)常用方法
判断文件类型、获取文件信息
创建文件、删除文件功能
注意:delete方法默认只能删除文件和空文件夹,delete方法直接删除不走回收站
遍历文件夹
listFiles方法注意事项:
- 当文件不存在时或者代表文件时,返回null
- 当文件对象代表一个空文件夹时,返回一个长度为0的数组
- 当文件对象是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
- 当文件对象是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
- 当没有权限访问该文件夹时,返回null
2、补充知识
(1)方法递归
什么是方法递归?
- 递归做为一种算法在程序设计语言中广泛应用。
- 方法调用自身的形式称为方法递归( recursion)。
递归的形式
- 直接递归:方法自己调用自己。
- 间接递归:方法调用其他方法,其他方法又回调方法自己。
方法递归存在的问题?
- 递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出现象
递归算法三要素大体可以总结为
- 递归的公式: f(n) = f(n-1) * n;
- 递归的终结点:f(1)
- 递归的方向必须走向终结点:
案例1:递归求1~n的和
分析:
① 假如我们认为存在一个公式是 f(n) = 1 + 2 + 3 + 4 + 5 + 6 + 7 + …(n-1) + n;
② 那么公式等价形式就是: f(n) = f(n-1) + n
③ 递归的终结点:f(1) = 1
④ 如果求的是 1-5的和的结果,应该如何计算。
⑤ f(5) = f(4) + 5
f(4) = f(3) + 4
f(3) = f(2) + 3
f(2) = f(1) + 2
f(1) = 1
代码:
import java.util.Scanner; public class Test1 { public static void main(String[] args){ Scanner read=new Scanner(System.in); System.out.print("请输入n的值:"); while(read.hasNext()){ int n= read.nextInt(); int result=f(n); System.out.println("1~"+n+"的和为:"+result); } } public static int f(int n){ if(n==1){ return 1; }else{ return n+f(n-1); } } }
示例:
请输入n的值:8 1~8的和为:36 5 1~5的和为:15 78 1~78的和为:3081
案例2:猴子吃桃问题
案例:猴子第一天摘下若干桃子,当即吃了一半,觉得好不过瘾,于是又多吃了一个 第二天又吃了前天剩余桃子数量的一半,觉得好不过瘾,于是又多吃了一个以后每天都是吃前天剩余桃子数量的一半,觉得好不过瘾,又多吃了一个等到第10天的时候发现桃子只有1个了。
需求:请问猴子第一天摘了多少个桃子?
分析: 整体来看,每一天都是做同一个事件,典型的规律化问题,考虑递归三要素:
① 递归公式:f(n)=(f(n+1)+1)*2
② 递归终结点:f(10)=1
③递归方向:f(1)=(f(2)+1)*2
f(2)=(f(3)+1)*2
······
f(8)=(f(9)+1)*2
f(9)=(f(10)+1)*2
f(10)=1
代码:
public class Test2 { public static void main(String[] args){ int result=f(1); System.out.println("第一天摘的桃子数为:"+result); } public static int f(int n){ if(n==10){ return 1; }else{ return (f(n+1)+1)*2; } } }
示例:
第一天摘的桃子数为:1534
案例3:文件搜索
需求:文件搜索、从C:盘中,搜索出某个文件名称并输出绝对路径。
分析:
① 先定位出的应该是一级文件对象
② 遍历全部一级文件对象,判断是否是文件
③ 如果是文件,判断是否是自己想要的
④ 如果是文件夹,需要继续递归进去重复上述过程
代码:
import java.io.File; public class Test4 { public static void main(String[] args){ searchFile(new File("C:/"),"idea64.exe");//输入根目录,要搜索的文件 } public static void searchFile(File dir,String fileName){ if(dir!=null && dir.isDirectory()){ //判断dir是否是目录 File[] files=dir.listFiles();//提取当前文件下的一级文件对象 if(files != null && files.length>0){//判断是否存在一级文件对象 for(File file:files){ if(file.isFile()){//判断当前遍历的一级文件对象是文件还是目录 if(file.getName().contains(fileName)){ System.out.println("找到了:"+file.getAbsolutePath());//文件绝对路径 //可以启动 //Runtime r=Runtime.getRuntime(); //r.exec(file.getAbsolutePath()); } }else{//为文件夹 searchFile(file,fileName); } } } }else{ System.out.println("no"); } } }
找不到电脑文件的小伙伴可以使用此程序找到,比电脑自己搜索要快多啦
示例:
no 找到了:C:\Users\Eastward\Desktop\idea64.exe.lnk 找到了:C:\Users\Eastward\Desktop\Java\资料\ideaIC-2022.1.3.win\bin\idea64.exe
案例4:啤酒问题
需求: 啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶, 请问10元钱可以喝多少瓶酒,剩余多少空瓶和盖子。
代码:
public class Test5 { public static int totalNumber; //总数 public static int lastBottleNumber;//剩余瓶子的数量 public static int lastCoverNumber;//剩余瓶盖的数量 public static void main(String[] args){ buy(10); System.out.println("总数:"+totalNumber); System.out.println("剩余瓶盖的数量:"+lastCoverNumber); System.out.println("剩余瓶子的数量:"+lastBottleNumber); } public static void buy(int money){ int buyNumber=money/2; totalNumber+=buyNumber; 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); } } }
示例:
总数:15 剩余瓶盖的数量:3 剩余瓶子的数量:1
(2)字符集
字符集基础知识:
- 33字符集(Character Set)是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集有:ASCII字符集(使用1个字节存储一个字符,一个字节是8位) 、GBK字符集(中一个中文字符一般以两个字节的形式存储) 、Unicode(UTF-8)·字符集(一个中文一般以三个字节的形式存储,同时也要兼容ASCII编码表)等。
汉字存储和展示过程解析
字符集的编码、解码操作:
String编码
String解码
3、IO流
(1)概述
I表示intput,把硬盘文件中的数据读入到内存的过程,称之输入,负责读。
O表示output,把内存中的数据写出到硬盘文件的过程,称之输出,负责写。
IO流的分类
IO流体系
总结
- 字节输入流 InputStream(读字节数据的)
- 字节输出流 OutoutStream(写字节数据出去的)
- 字符输入流 Reader(读字符数据的)
- 字符输出流 Writer(写字符数据出去的
(2)字节流
文件字节输入流:FileInputStream
作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。
- 每次读取一个字节
- 每次读取一个字节数组
- 读取文件的全部字节
文件字节输出流:FileOutputStream
作用:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流。
流的关闭与刷新
(3)案例:文件拷贝
需求: 把某个视频复制到其他目录下的“b.avi”
思路:
① 根据数据源创建字节输入流对象
② 根据目的地创建字节输出流对象
③ 读写数据,复制视频
④ 释放资源
代码:
import java.io.*; public class Test6 { public static void main(String[] args){ try { InputStream is=new FileInputStream("这里输入需要复制文件的路径。"); OutputStream os=new FileOutputStream("输入复制文件的位置。"); byte[] buffer=new byte[1024]; int len; while((len=is.read(buffer))!=-1){ os.write(buffer,0,len); } System.out.println("复制完成!"); os.close(); is.close(); } catch (Exception e) { e.printStackTrace(); } } }
(4)资源释放的方式
try-catch-finally
finally:放在try-catch后面的,无论是正常执行还是异常执行代码,最后一定要执行,除非JVM退出。
作用:一般用于进行最后的资源释放操作(专业级做法)
格式:
try-with-resource
JDK 7和JDK9中都简化了资源释放操作
作用:自动释放资源、代码简洁