1.文件
1.1什么是文件
文件分为狭义的文件和广义的文件。
狭义的文件:保存在硬盘的文件。
广义的文件:操作系统进行资源管理的一种机制,很多的软件、硬件资源抽象成文件来进行表示。(println控制台的标准输出,scanner控制台的标准输入,都是针对广义的文件)。
我们这里主要谈的是狭义的文件,文件夹是不是文件是文件,但是文件夹用专业术语说其实是目录。mysql存贮数据的时候也是把数据保存在硬盘上的。相比与硬盘存储数据,其实还有内存和cpu寄存器也是可以存储的。接下来我们可以回忆一下它们之间的差别。
存储空间 访问速度 成本 持久化
硬盘 很大(几个TB) 很慢 便宜 持久断点之后数据仍然存在
内存 更小(16GB 32GB) 快 贵 不能持久
cpu寄存器 非常小(不到 1KB) 非常快 贵 不能持久
硬盘分为机械硬盘和固态硬盘,机械硬盘的访问速度没有固态硬盘的访问速度快,固态硬盘也就一秒访问几个GB, 相比之下内存比硬盘快上好几倍好几千倍,cpu比内存也是几百上前级别的。
机械硬盘速度之所以这么慢主要是受限于内部结构。
1.2 文件路径
一台计算机中能够保存的文件有很多,那如何进行区分呢?我们一般是通过路径来定位文件的一系列过程。计算机中目录套目录构成树形结构(N叉树)。把树根开始,到最终的文件中间都需要经历哪些目录,把这些目录记录下来就成路径。一般使用“/”来分割路径中的多级目录,主流操作系统使用“/”来分割,但是Windows时例外,Windows支持反斜杠和正斜杆(反“\” 正“/”),代码中涉及路径最好使用正斜杠,反斜杆要使用转义字符如,如下所示:
说到路径这里又分为绝对路径和相对路径。绝对路径是从盘符开始逐级表示出来
相对路径描述的是一个基准路径,这里的 “.” 点表示当前所在目录的位置,“..”表示当前路径的上一层路径。如果一个文件的绝对路径如上所示,则相对路的表示方式如下
如果是左边这样的形式首先是要返回共同目录在共同目录下寻找我们需要的目录。
谈到相对路径要先明确基准路径,如果一个代码中写一个相对路径那基准路径又是谁??
真正有效的工作路径是谁我们是没法确定的,取决于你程序运行的方式。
1.在IDEA中直接运行基准路径就是项目的目录(保存这份代码的目录)。
2.打一个jar包,单独运行jar包。当前在哪个目录下执行运行命令(java -jar jar包名)基准目录就是那个目录。
3.如果打成一个war包,放到tomcat中运行,此时基准目录就是tomcat的bin目录
1.3文件的种类
从开发的角度,把文件分成两类。一是文本文件,二是二进制文件。所有的文件都是二进制的但是有一些是特殊的,有些二进制数据刚好能构成字符(一个汉字占几个字节?不同编码方式是不一样的,UTF-8下一个汉字占三个字节,gbk下一个汉字占两个字节),二进制数据恰好都在码表上能够查到,并且翻译过来都是有意义的信息。实际开发中判断某一个文件是否是文本,简单粗暴的办法直接使用记事本打开,打开之后看是不是乱码,能看懂的话是文本,看不懂的话就是二进制。图片、音频、视频可执行程序都是典型的二进制文件,txt纯文本,java.c都是典型的文本文件,word docx这样的文件是文本还是二进制文件呢?其实都是二进制文件,docx是富文本不仅仅是文本内容还有各种格式信息还有图片多媒体信息。
2.操作文件
java标准库中提供了一系列的类操作文件
1.是文件系统操作,创建文本,删除文件,重命名,创建目录
2.文件内容操作,针对一个文件的内容进行读和写
2.1file概述
我们来看看file类中常见属性、构造方法和方法
构造方法中,参数String文件的路径使用绝对路径和相对路径均可
pathSeparator是分隔符
getPath()可能返回的是相对路径也可能是绝对路径
2.2 详细操作使用
2.2.1 关于文件路径相关构造方法
import java.io.File;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
File file = new File("D:/clash");
System.out.println(file.getParent());
System.out.println(file.getName());
System.out.println(file.getPath());
System.out.println(file.getAbsoluteFile());
System.out.println(file.getCanonicalPath());
}
}
构造方法getPath传入的是绝对路径,此处getPath就是得到绝对路径 。
如果我们把代码稍微改一下变成相对路径,那么这里的情况又会不一样。
getCanonicaPath是绝对路径的简化版,这里把点什么的都省略了
2.2. 2 关于文件创建以及存在状态的构造方法
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
public class Demo3 {
public static void main(String[] args) throws IOException {
File file = new File("./test.txt");
//file.createNewFile();
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
}
}
这里由于文件并不是真实存在所以返回的都是false,但是这里也可以手动创建文件 file.createNewFile();加上之后结果肯定是不一样的啦
2.2.3 关于删除文件操作的构造方法
关于delete
import java.io.File;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
File file = new File("./test.txt");
file.createNewFile();
boolean result = file.delete();
System.out.println(result);
}
}
关于deleteOnExit
import java.io.File;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException, InterruptedException {
File file = new File("./test.txt");
//在进程退出时删除文件
file.deleteOnExit();
Thread.sleep(1000);
}
}
在项目所在的目录下创建 文件运行成功后自动删除文件
这样的设定应用场景比较广泛,当我们使用world、ppt、excel做一些大作业,电脑突然没电了文档还没有保存,那文档白写了吗?但是其实我们再次打开的时候world等软件会提示你是否恢复上次未保存的文件。那为什么会出现这样的情况这就和我们上面提到的deletOnExit有关,office等系列软件都会在你编辑文档的过程中产生一个隐藏的临时文件同时保存你正在编译的内容。如果office异常关闭,这个临时文件就仍然存在,下次启动office就可以从这个临时文件中恢复上次正在编译的内容。如果是正常关闭那么就会使用上述的 deleteOnExit 进程结束就会使文件删除。
2.2.3 关于list
list
import java.io.File;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Demo2 {
public static void main(String[] args) {
// 针对文件我们是无法list只能针对目录
File file = new File("./");
// File[] s1 = file.listFiles();
//list 和 listFiles 其实都是一样的只是返回的类型不一样
String[] s = file.list();
System.out.println(Arrays.toString(s));
}
}
listFIles
import java.io.File;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Demo2 {
public static void main(String[] args) {
// 针对文件我们是无法list只能针对目录
File file = new File("./");
//list 和 listFiles 其实都是一样的只是返回的类型不一样
//String[] s = file.list();
File[] s1 = file.listFiles();
System.out.println(Arrays.toString(s1));
}
}
listFIles这里获取的类型是file我们可以使用file获取更多的操作,如下所示:
File[] s1 = file.listFiles();
if (s1 != null) {
for (File f : s1) {
System.out.println("Name: " + f.getName());
System.out.println("Size: " + f.length() + " bytes");
System.out.println("Is Directory: " + f.isDirectory());
System.out.println("Last Modified: " + new Date(f.lastModified()));
System.out.println("------------------------");
}
}
list、listFlles只能列出当前目录里面的子元素,无法列出子目录中的内容。
2.2.4mkdir、mkdirs
这两个都是创建目录的意思,这了的mk就是make的意思,dir是directory的意思。相比较于mkdir创建一级目录这里的mkdirs是创建多级目录,Linux就是通过mkdir命令来创建目录的。
创建成功这里返回的就是true
这里显示创建失败是因为mkdir不能创建多级目录只能创建一级目录前面我们已经说过。要创建多级目录当然要使用mkdirs,如下所示:
成功的话test里面就有111,111里面就有22
2.2.4 renameTo(重命名)
关于目录文件的移动
import java.io.File;
public class Demo4 {
public static void main(String[] args) {
File file = new File("./test2");
File file1 = new File("./src/test2");
//重命名
boolean result = file.renameTo(file1);
System.out.println(result);
}
}
此时test2文件就到src目录下,从操作系统来看移动和重命名是一样的本质,这样的操作通常速度极快时间复杂度为O(1)如果是复制的话时间复杂度就是O(n)。如果你的移动操作跨硬盘了此时相当于复制+删除,复制到另一个硬盘再删除之间所在目录,这里说的跨硬盘不是说跨C盘D盘这种这些是属于一个硬盘。