引言
1. 对文件的初步认识
狭义的文件,一般可以分成两个大类:
① 普通文件( 不可再分 )
② 目录文件( 文件夹 )
2. 绝对路径和相对路径
一、File 类
File 类对应的方法
创建一个文件
这是创建一个 " .txt " 文件最基本的操作,我们需要先进行判定是否重名。
import java.io.File; import java.io.IOException; public class Test { public static void main(String[] args) throws IOException { String filepath = "D:/Data/123.txt"; File file = new File(filepath); if (!file.exists()) { file.createNewFile(); } else { System.out.println("文件名已存在,无法创建!"); } } }
测试一
程序清单1:
import java.io.File; import java.io.IOException; public class Test1 { public static void main(String[] args) throws IOException { //输入代码的时候使用 / ,这样避免了转义字符的语法麻烦 File file = new File("d:/test.txt"); System.out.println(file.getParent()); System.out.println(file.getName()); System.out.println(file.getPath()); System.out.println(file.getAbsoluteFile()); System.out.println(file.getCanonicalFile()); System.out.println("-------------------------"); File file2 = new File("./test.txt"); System.out.println(file2.getParent()); System.out.println(file2.getName()); System.out.println(file2.getPath()); System.out.println(file2.getAbsoluteFile()); System.out.println(file2.getCanonicalFile()); } }
输出结果:
在 IDEA 编译器中,当我们运行一个程序,此时的工作目录就是当前项目所在的目录,而在代码中涉及到的相对路径,其实也就是以这个当前项目所在的目录作为基准。在 IDEA 中,可以通过如下方法来找到当前的工作目录。
当然,代码除了在 IDEA 中,也可以直接通过命令行来运行。如果是通过命令行运行,当前命令行所在的目录,就是工作路径。比方说:windows 的 cmd 控制台
测试二
我们在当前的工作目录中,创建一个 .txt 的文件,三秒之后,我们再将它删除。
注意:我通过 File 类创建出来一个新的对象时,下面的代码并没有为文件加 ./ 或 …/
那么,这其实相当于省略了 ./
File file = new File("hello world.txt");
程序清单2:
import java.io.File; import java.io.IOException; public class Test2 { public static void main(String[] args) throws IOException, InterruptedException { File file = new File("hello world.txt"); System.out.println(file.createNewFile()); Thread.sleep(3000); System.out.println(file.delete()); } }
在我们创建文件的时候,会抛出异常:throws IOException,这是为什么?
① 权限问题。因为创建文件之后,你可能对这个文件进行读、写、修改等操作,而为了安全,这就不支持所有用户者都能使用。这就好像有的文件需要管理员才能运行,一个道理。
② 磁盘空间不够。
测试三
我们准备对测试二进行改造,当下面的整个代码执行完之后,起初创建的文件才会被删除。也就是,总共十秒后,文件才会被删除。
程序清单3:
import java.io.File; import java.io.IOException; public class Test3 { public static void main(String[] args) throws IOException, InterruptedException { File file = new File("hello world.txt"); System.out.println(file.createNewFile()); System.out.println("文件创建成功"); Thread.sleep(3000); file.deleteOnExit(); System.out.println("把文件标记成【退出则删除的状态】"); Thread.sleep(7000); } }
这个思想对于实际使用文件的场景下,具有非常大的意义。
举个例子:你通过电脑编辑文档的时候,突然断电了,如果应用了这个思想,它就会产生效果。现在的 Office,当你每次编辑文件的时候,它都会产生一个临时文件,以防意外发生。当你真的停电了关机了,内存中的数据一定会丢失,但下一次开机的时候, Office 就会问你是否恢复上次的文档,你可以通过临时文件将数据备份回来。
测试四
我们来演示一下当前工作目录下的所有文件名( 文件夹 + 文件 )
程序清单4:
import java.io.File; import java.util.Arrays; public class Test4 { public static void main(String[] args) { File file = new File("."); String[] files = file.list(); System.out.println(Arrays.toString(files)); } }
输出结果:
测试五( 面试题 )
面试题:有什么办法能够将一个目录下的所有文件夹对应的所有文件全部打印出来呢?
通过递归来实现。
在 getAllFiles 方法中,我们接收某个工作目录,之后通过递归的方法来搜寻。这个思想和树这个数据结构的思想是相同的,当我们找到的文件是叶子节点,说明这个文件已不再可分,就直接返回,这也就是递归的边界条件;而当我们找到的是目录( 文件夹 ),那么说明还没到树的最底下,我就得继续递归。
程序清单5:
import java.io.File; import java.util.ArrayList; import java.util.List; //通过递归的方式,来罗列目录中的所有文件 public class Test5 { public static List<String> list = new ArrayList<>(); public static void getAllFiles (String basePath) { File file = new File(basePath); //如果是文件,说明已经无法再拆分了 if (file.isFile()) { list.add(basePath); return; } else if (file.isDirectory()){ //如果是目录,或者说是文件夹,说明还能继续往下打开 String[] files = file.list(); for (String s : files) { getAllFiles(basePath + "/" + s); } } else { //当前文件既不是普通文件,也不是目录,这个情况暂不考虑 //scoket 文件、管道文件、设备快文件... } } public static void main(String[] args) { getAllFiles("."); for (String s : list) { System.out.println(s); } } }
输出结果:
测试六
演示创建目录的两种方法,一个 mkdir 方法只能创建一个主目录。
而 mkdirs 方法,不但能创建主目录,还能创建主目录下的子目录。
程序清单6:
import java.io.File; import java.io.IOException; public class Test6 { public static void main(String[] args) throws IOException { File file = new File("demo"); file.mkdir(); File file2 = new File("demo2/aaa/bbb"); file2.mkdirs(); } }
测试七
测试 rename 重命名方法,它有两个功能。
① 重命名
② 可以将一个文件从一个目录移动到另外一个目录中
程序清单7 :
import java.io.File; import java.io.IOException; public class Test7 { public static void main(String[] args) throws IOException { File file1 = new File("./123.txt"); File file2 = new File("./456.txt"); file1.renameTo(file2); File file3 = new File("./out/456.txt"); file2.renameTo(file3); } }
上面的代码执行了两个步骤
步骤一:将文件 123 重命名为 456