前言
本篇介绍文件的基本操作,认识文本文件与二进制文件的区别,什么是绝对路径与相对路径,java标志库中又是如何进行文件操作的;认识流对象进行简单的文件读取操作;如有错误,请在评论区指正,让我们一起交流,共同进步!
文章目录
- 前言
- 1. 文件的存储
- 2.文件系统操作 - 通过标准库操作
- 2.1 认识文件的路径
- 2.2 认识 绝对路径 与 相对路径
- 2.3 认识文本文件 与 二进制文件
- 2.4 标准库中的文件 - File
- 3.文件内容操作
- 3.1 对于文本文件 - 字符流
- 3.2 对于二进制文件 - 字节流
- 4. 练习 - 遍历目录,查找文件内容
- 总结
本文开始
1. 文件的存储
文件一般都存储在硬盘上;
硬盘存储 与 内存存储区别:
① 速度: 内存存储速度比硬盘快
② 空间大小:内存存储空间比硬盘小
③ 成本:内存成本比硬盘贵
④ 持久化:内存掉电后,数据会丢失;外存掉电后数据不会丢失
2.文件系统操作 - 通过标准库操作
2.1 认识文件的路径
文件系统是以 树形 结构来组织文件和目录;
文件路径:目录在系统上的具体位置 - (目录 <=> 文件夹),通过树根节点,延树杈一步一步到达目标文件所经过的路径;
表示路径的方式:字符串,每个目录之间用 \ 或者 / 来分隔;
【注】反斜杠 \ 在代码中需要使用转义字符 \ 代表一个 \ ;
示例:
2.2 认识 绝对路径 与 相对路径
绝对路径:从盘符开始,一层一层得到的路径;
相对路径:从某个目录出发(./ 或者 …/ 开始),一层一层找到的路径;- 需要有一个基准目录;
【注】./ 表示相对路径中的当前目录; …/ 表示当前目录的上一级目录;
相对路径中一定要明确基准目录是什么!!!;
文件系统中,任何一个文件,对应的路径是唯一的,没有两个路径相同的文件;
2.3 认识文本文件 与 二进制文件
文本文件:存储的是文本,内容由ASCII字符 或 其他字符编码得到;
二进制文件:存储的二进制的数据; - 存储不受限制;
怎么区分文本文件 与 二进制文件呢?
文本文件:内容人能够看懂
例如:.txt, .csa - excel等;
二进制文件:内容数据人看不懂;
例如:.exe, .mp3等;
二进制文件图示:
2.4 标准库中的文件 - File
File 类:Java标准库中,提供的,它是对硬盘上一个文件的抽象表示,用于间接操作硬盘中的文件;
【注】文件存储在硬盘中,不能之间操作硬盘中的文件;使用File对象,先在内存中创建一个File对象,操作这个对象,间接操作硬盘中的文件;
2.4.1 构造文件对象的构造方法
构造对象:可以使用绝对路径 / 相对路径 进行初始化构造;
【注】路径指向的文件可存在,也可不存在;
2.4.2 File对象的方法
File对象的基本操作:
public static void main(String[] args) throws IOException {
//通过File对象操作
File file = new File("d:/dog.jpg");
//返回父目录文件路径
file.getParent();
//获取路径对象的文件名
file.getName();
//获取文件路径
file.getPath();
//获取文件绝对路径
file.getAbsoluteFile();
//对绝对路径进行化简得到的结果
file.getCanonicalFile();
}
判断文件是否存在,创建文件再次查看;
public static void main2(String[] args) throws IOException {
File file = new File("./t.text");
//文件是否存在
System.out.println(file.exists());
System.out.println(file.isFile());
System.out.println(file.isDirectory());//目录是否存在
//创建文件
System.out.println("----创建文件----");
file.createNewFile();
System.out.println(file.exists());
System.out.println(file.isFile());
System.out.println(file.isDirectory());
System.out.println("----删除文件----");
file.delete();
System.out.println(file.exists());
}
创建文件目录,再查看文件名 / 文件;
public static void main(String[] args) {
File file = new File("t-dir/a/b");
//创建一级目录
//file.mkdir();
//创建多级目录
file.mkdirs();
File file = new File("t-dir");
//list() - 返回字符串
//返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。
//File对象代表的目录下的所有 文件名
String[] results = file.list();
System.out.println(Arrays.toString(results));
//listFiles() - 返回文件
//返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件。
//File对象代表的目录下的所有 文件 - File对象表示
File[] r2 = file.listFiles();
System.out.println(Arrays.toString(r2));
}
3.文件内容操作
3.1 对于文本文件 - 字符流
文本文件: 读写的基本单位是字符
输入:Reader - 读硬盘
输出: Writer - 写硬盘
3.2 对于二进制文件 - 字节流
二进制文件:读写的基本单位是字节;
输入:InputStream
输出:OutputStream
如何区分流对象输入输出方向?
以cpu为基准 - 输入输出是站在CPU的角度来看的;
输入:从硬盘读到内存中称为输入;
输出:从内存写入到硬盘是是输出;
a) 使用InputStream
由下图可知InputStream是抽象类,不能够new对象,这里就是new它的子类new FileInputStream();
【注】记得关闭文件,如果不及时关闭,会出现文件资源泄露问题;
读取字节的多个方法:
【注】read方法读取完毕会返回-1,所以用int接收字节;
读取字节代码实现:
public static void main(String[] args) throws IOException {
//java代码的语法,使用try() {}
//带有资源的try操作,会在try代码块结束,自动执行close关闭操作
//InputStream实现了一个特定的接口Closeable,实现了这个接口就可以使用这种语法,
// 在代码块结束时自动调用Closeable去关闭资源;
try(InputStream inputStream = new FileInputStream("d:/t.txt")) {
while (true) {
//使用Int接收读到的字节,为了表示-1,-1代表了读取字节结束的标志;
int b = inputStream.read();
if (b == -1) {
break;
}
//读取的字节,显示的是ascii码值
System.out.println(b);
}
}
}
为什么使用try()这种语法?
可以自动关闭文件资源;文件打开后需要及时关闭,如果没有及时关闭会出现文件资源泄露;不使用try()也没关系,但需要自己手动关闭文件,为了更好的优化代码,所以使用try()这种语法;
b) OutputStream
写入字节的方法:
写入字节代码实现:
public static void main(String[] args) {
try(OutputStream outputStream = new FileOutputStream("d:/t.txt")) {
outputStream.write(97);
outputStream.write(98);
} catch (IOException e) {
e.printStackTrace();
}
}
c) Read
读取字符方法:
读取字符代码实现:
public static void main(String[] args) {
try(Reader reader = new FileReader("d:/t.txt")) {
while (true) {
int n = reader.read();
if(n == -1) {
break;
}
char ch = (char) n;
System.out.println(ch);
}
} catch (IOException e) {
e.printStackTrace();
}
}
d) Write
写的方法
写的代码实现:
public static void main(String[] args) {
try (Writer writer = new FileWriter("d:/t.txt")){
writer.write(99);
writer.write(99);
} catch (IOException e) {
e.printStackTrace();
}
}
4. 练习 - 遍历目录,查找文件内容
前提:
电脑中有许多文件,用户需要查找含有word关键词的文件;
如何操作呢?
使用递归操作,把一个盘中的文件挨个判断是否含有关键词,含有关键词就打印文件路径,不含有继续递归;
4.1 简单的模式:
首先输入某个盘符c:/ 或者某个具体位置;
再输入需要查找的关键词word;
根据盘符 / 某个具体路径 和 关键词查找文件,进行递归操作;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//1.用户指定要搜索的根目录
System.out.println("请输入根目录:");
File rootDir = new File(scanner.next());
if(!rootDir.isDirectory()) {
System.out.println("输入有错误,请重新输入!");
return;
}
//2.用户输入一个要查询的词
System.out.println("请输入要查询的词: ");
String word = scanner.next();
//3.递归的进行目录 / 文件的遍历
scanDir(rootDir,word);
}
4.2
递归操作:
① 根据根目录把所有文件放到 File[ ] 数组中
② 遍历File[ ] 数组,判断 是目录 还是普通文件 或者其它;
③ 如果是目录 根据当前文件为根目录进行递归;如果是其它文件之间下一个;如果是文件判断该文件内容中是否含有要查找的关键词;
private static void scanDir(File rootDir, String word) {
//列出根文件中的内容
File[] files = rootDir.listFiles();
if (files == null) {
//空目录,直接返回,不用递归
return;
}
//遍历目录中的内容
for (File f : files) {
System.out.println("当前搜索到:" + f.getAbsoluteFile());
if(f.isFile()) {
//打开文件,读取内容,比较是否包含关键词
String content = readFile(f);
if(content.contains(word)) {
System.out.println(f.getAbsolutePath() + "包含关键词!");
}
}else if(f.isDirectory()) {
//目录,进行递归操作
//这里以f为新的根目录
scanDir(f,word);
}else {
//不是文件,也不是目录
continue;
}
}
}
4.3
读文件操作:判断文件内容是否含有关键词:
① 先读取文件内容,使用Read一个一个读取字符 - 这里指定使用字符串;
② 读取的结果使用 StringBuilder 进行字符串拼接
③ 最后返回 StringBuilder 字符串;
private static String readFile(File f) {
//这里匹配的是字符串,所以使用字符流
StringBuilder stringBuilder = new StringBuilder();
try(Reader reader = new FileReader(f)) {
//读取一个个字符到stringBuilder中拼接成 字符串
while (true) {
int c = reader.read();
if(c == -1) {
break;
}
//拼接字符成一个字符串
stringBuilder.append((char)c);
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
总结
✨✨✨各位读友,本篇分享到内容如果对你有帮助给个👍赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!