1.前言
存储数据的方案:
有四种存储数据的方法:变量、数组、对象、集合。
共有特点:都是内存中的数据容器。在断电、程序终止时会丢失。
想要长久保存需要放到文件或者数据库中,存储在硬盘中,File类就是帮助我们来执行这个操作的。
2.File
File时Java.io.包下的类,File的对象,用于代表当前操作系统的文件或文件夹。
File只能对文件本身进行操作,不能读取文件里存储的数据。
使用IO流可以读写文件或数据。将磁盘里的数据读到内存中。
3.使用
创建File类的对象
public class test {
public static void main(String[] args) {
// 1. 创建一个File对象。指代某个具体的文件。
// 路径分隔符
// File f1 = new File("D:/resource/ab.txt");
// File f1 = new File("D:\\resource\\ab.txt");
File f1 = new File("D:" + File.separator + "resource" + File.separator + "ab.txt");
System.out.println(f1.length()); // 文件大小
// 注意:File对象可以指代一个不存在的文件路径
File f3 = new File("D:/resource/aaaa.txt");
System.out.println(f3.length());
System.out.println(f3.exists()); // false
// 想指定定位的文件在模块中。应该怎么定位?
// 绝对路径: 带盘符的
// File f4 = new File("D:\\code\\javasepromax\\file-io-app\\src\\a.txt");
// 相对路径 (建议):不带盘符,默认从工程目录下寻找文件的。
File f4 = new File("file-io-app\\src\\a.txt");//从模块名开始
System.out.println(f4.length());
}
}
有三种路径分隔符。
判断文件类型、获取文件信息
// 7. public long lastModified():获取文件的最后修改时间。
File f1 = new File("D:/resource/ab.txt");
long time = f1.lastModified();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
System.out.println(sdf.format(time));
// 8. public String getPath():获取创建文件对象时给的路径
File f2 = new File("D:/resource/ab.txt");
File f3 = new File("file-io-app\\src\\a.txt");
System.out.println(f2.getPath());
System.out.println(f3.getPath());
// 9. public String getAbsolutePath():获取绝对路径
System.out.println(f2.getAbsolutePath());
System.out.println(f3.getAbsolutePath());
创建和删除文件夹
public class test {
public static void main(String[] args) throws Exception {
// 1. public boolean createNewFile():创建一个新文件(文件内容为空),创建成功返回true,反之。
File f1 = new File("D:/resource/itheima2.txt");
System.out.println(f1.createNewFile());
// 2. public boolean mkdir():用于创建文件夹,注意:只能创建一级文件夹
File f2 = new File("D:/resource/aaa");
System.out.println(f2.mkdir());
// 3. public boolean mkdirs():用于创建文件夹,注意:可以创建多级文件夹
File f3 = new File("D:/resource/bbb/ccc/ddd/eee/fff/ggg");
System.out.println(f3.mkdirs());
// 4. public boolean delete():删除文件或者空文件夹,注意:不能删除非空文件夹
System.out.println(f1.delete());
System.out.println(f2.delete());
File f4 = new File("D:/resource");
System.out.println(f4.delete());
}
}
遍历文件夹
public class test {
public static void main(String[] args) {
// 1. public String[] list():获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
File f1 = new File("D:\\course\\特研内容");
String[] names = f1.list();
for (String name : names) {
System.out.println(name);
}
// 2. public File[] listFiles():(重点)获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)
File[] files = f1.listFiles();
for (File file : files) {
System.out.println(file.getAbsolutePath());
}
}
}
4.多级遍历
方法递归(recursion)
递归是一种算法,在程序审设计语言中广泛使用。
从形式上说,方法调用自身的形式称为方法递归。分为直接递归和间接递归,前者是方法调用自己,后者是方法先调用其他方法,再由其他方法调用回去。
public class RecursionTest1 {
public static void main(String[] args) {
test1();
}
// 直接方法递归
public static void test1() {
System.out.println("---test1---");
test1(); // 直接方法递归
}
// 间接方法递归
public static void test2() {
System.out.println("---test2---");
test3();
}
public static void test3() {
test2(); // 间接递归
}
}
注意:递归如果没有控制好终止的话,会出现递归死循环,导致栈内存溢出错误。
案例:求阶乘
public class test {
public static void main(String[] args) {
System.out.println("5的阶乘是:" + f(5));
}
public static int f(int n) {
// 终结点
if (n == 1) {
return 1;
} else {
return f(n - 1) * n;
}
}
}
案例:文件搜索
从D盘中,搜索QQ.exe文件,找到后输出位置。
public class test {
public static void searchFile(File dir, String fileName) {
// 1. 定制合法的前提提搜金定
if (dir == null || !dir.exists() || dir.isFile()) {
return; // 代表无法搜索
}
// 2. dir不是null, 存在,一定是目录对象。
// 获取当前目录下的全部一级文件对象。
File[] files = dir.listFiles();
// 3. 判断当前目录下是否存在有一级文件对象,以及是否可以获取到一级文件对象。
if (files != null && files.length > 0) {
// 4. 遍历全部一级文件对象。
for (File f : files) {
// 5. 判断当前是是否是文件, 还是文件夹
if (f.isFile()) {
// 是文件,判断这个文件名是否是我们要找的
if (f.getName().contains(fileName)) {
System.out.println("找到了:" + f.getAbsolutePath());
}
} else {
// 是文件夹,继续重复这个过程(递归)
searchFile(f, fileName);
}
}
}
}
public static void main(String[] args) {
File dir = new File("D:\\course");
searchFile(dir, "目标文件名");
}
}
案例:删除文件或文件夹
public class test {
public static void deleteDir(File dir) {
if (dir == null || !dir.exists()) {
return;
}
if (dir.isFile()) {// 是文件,直接删除
dir.delete();
return;
}
// 1. dir存在且是文件夹,拿里面的一 级文件对象
File[] files = dir.listFiles();
if (files == null) {
return;
}
// 2. 这是一个有内容的文件夹,干掉里面的内容,再干掉自己。
for (File file : files) {
if (file.isFile()) {
file.delete();
} else {
deleteDir(file);
}
}
dir.delete();
}
public static void main(String[] args) {
File dir = new File("D:\\要删除的目录");
deleteDir(dir);
}
}
案例:啤酒问题
/**
* 啤酒两元一瓶,两个空瓶可以换一瓶啤酒,四个盖子也可以换一瓶啤酒,十元可以喝几瓶。
*/
public class BottleExchange {
static int totalNumber = 0; // 总买瓶数
static int lastCoverNumber = 0; // 剩余盖子数
static int lastBottleNumber = 0; // 剩余瓶子数
public static void main(String[] args) {
int initialMoney = 10; // 初始金额
buy(initialMoney);
System.out.println("总数数:" + totalNumber);
System.out.println("剩余盖子数:" + lastCoverNumber);
System.out.println("剩余瓶子数:" + lastBottleNumber);
}
public static void buy(int money) {
// 1. 先买啤酒
int buyNumber = money / 2;
totalNumber += buyNumber;
// 2. 把盖子和瓶子换成钱继续买
// 计算本轮总的瓶子和瓶盖数
int allBottleNumber = buyNumber + lastBottleNumber;
int allCoverNumber = buyNumber + lastCoverNumber;
int allMoney = 0;
if (allBottleNumber >= 2) {
allMoney += (allBottleNumber / 2) * 2;
lastBottleNumber = allBottleNumber % 2;
}
if (allCoverNumber >= 4) {
allMoney += (allCoverNumber / 4) * 2;
lastCoverNumber = allCoverNumber % 4;
}
if (allMoney >= 2) {
buy(allMoney);
}
}
}