1.File与IO流
File类就是代表系统的文件 / 目录,IO流是用来处理File类的
File类
构造器
分隔符(三种)
第三种File.separator是跨平台的,获取当前操作系统的分隔符
常用方法
- length()
返回文件大小(字节),如果是目录,返回的是目录本身大小,而不是目录所有文件大小
- exists()
检测File制定的文件 / 目录路径是否存在
文件遍历 (两种)
public class MyTest {
public static void main(String[] args) {
// 1.public String[] list(), 获取当前目录下所有的"一级文件名称"到一个字符串数组中
File file = new File("D:\\DevelopTools\\IntelliJ IDEA 2023.2.3");
String[] names = file.list();
for (String name : names) {
System.out.println(name);
}
System.out.println("-------------------------------------");
// 2.public File[] listFiles():(重点)获取当前目录下所有的"一级文件对象"到一个文件对象数组中
File[] files = file.listFiles();
for (File file1 : files) {
System.out.println(file1);
}
}
}
前置知识
方法递归
递归形式
阶乘
不停调用归回到终结点f(1),return 1,开始递升
代码实现
public class MyTest {
public static void main(String[] args) {
System.out.println(recursion(3));
}
public static int recursion(int n){
return (n == 1) ? 1 : recursion(n - 1) * n;
}
}
内存图
案例:文件搜索
需求:从D:盘中,搜索"WeChat.exe"这个文件,找到后直接输出其位置
文件地址:"D:\\WeChat\\[3.9.11.25]\\WeChat.exe"
思路分析
代码实现
public class MyTest {
public static void main(String[] args) {
searchFile(new File("D:/"), "WeChat.exe");
}
public static void searchFile(File dir, String fileName){
// 1.把非法的情况都给拦截住
// dir参数不能为null,dir必须存在,不能是文件对象
if(dir == null || !dir.exists() || dir.isFile()){
System.out.println("无法搜索");
return;// 代表无法搜索
}
// 获取当前目录下的全部一级文件对象
File[] files = dir.listFiles();
// 集合对象要存在,集合内容不为空
if(files != null && files.length > 0){
// 遍历全部一级文件对象
for (File f : files){
// 判断是文件夹还是文件
if(f.isFile()){
// 是文件
if(f.getName().contains(fileName)){
System.out.println("找到了:" + f.getAbsolutePath());
}
}else {
// 是目录,继续重复这个过程(递归)
searchFile(f, fileName);
}
}
}
}
}
字符集
链接到我的之前写的一篇博客:常用编码格式,汉字和字母分别占用多大空间_unicode 占用-CSDN博客
标准ASCII字符集
码点
GBK字符集
Unicode字符集
最初只有美国人用电脑,后来各个国家开始用电脑,每个国家都需要弄一套自己的字符集,但是国际组织担心会乱套,于是呼吁大家不要自己搞,用我的Unicode
UTF-32
是一套Unicode字符集的一套编码方案,这个方案并不被大家所采纳,太浪费空间了,哪怕只是一个字节的标点符号,也需要开辟四个字节的空间,足足大了三倍
UTF-8
注意:技术人员在开发时都应该使用UTF-8编码!
注意点
编码与解码
常用方法
IO流
FIle类只能操作文件本身,对于文件中数据的操作还得用IO流
怎么学IO流?
流的分类(四种)
IO流的体系
FileInputStream
构造器
常用方法
读取一个字节(性能差&中文乱码)
这是个垃圾代码,开发中不会这么用的,学习一下思路就行
此方法性能很差,读取一个字节就需要调用一次硬盘资源。
程序运行在内存中,数据确实保存在硬盘中,程序调用硬件资源的开销,以及去硬盘中找资源的性能相对于内存来说是很差的
在开发中,应该尽量减少让程序调用硬件资源,以及读取硬盘数据的频次
其二,无法避免的中文乱码,开发环境中,中文编码默认是UTF-8,每次读取一个字节,强行截取掉两个字节,当然乱码了
必须释放资源
读取多个字节(中文乱码)
相比读取单个字节,减少了调用硬件资源的频次,提升了性能,但是依旧无法避免中文乱码问题
读取多少则倒出多少
15、IO流:文件字节输入流-每次读取多个字节_哔哩哔哩_bilibili
注意观察下图,一共五个字节,第一次读取三个字节,就是前三个[abc]
第二次又用buffer读取三个字节 ,但是就剩下两个字节了,他会进行新值覆盖旧值[66c],这样子就出事了,所以,将buffer看成水桶,那么读取多少就倒出多少
代码优化
依旧无法避免中文乱码
JDK17似乎底层优化了,并不会中文乱码,我试了很多遍,视频里的乱码了,但是并不清楚JDK8还是多少
读取全部字节(两种)
方式一(整数溢出)
其中的强转是有问题的,如果文件大小超过了1.99GB,就会整数溢出
除以 1024*1024*1024
方式二(推荐)
官方提供的方法,好用,不会整数溢出
- 是如何避免内存溢出的?
如果读取的文件大小大于内存大小,报异常
FileOutputStream
构造器
默认是覆盖文件数据,即先清除文件中的数据,再重写
也可以设置追加模式,给构造器设置true即可
常用方法
写出一个字节
综合案例:文件复制
public class MyTest {
public static void main(String[] args) throws Exception{
// 需求:复制照片
// 1.创建一个字节输入流管道与源文件接通
FileInputStream fis = new FileInputStream("C:\\Users\\63912\\Desktop\\源文件.txt");
// 2.创建一个字节输出流管道与目标文件接通
FileOutputStream fos = new FileOutputStream("D:\\pictures\\copy\\copy.txt");
byte[] buffer = fis.readAllBytes();
fos.write(buffer, 0, buffer.length);
fos.close();
fis.close();
System.out.println("复制完成!!");
}
}
public class MyTest {
public static void main(String[] args) throws Exception{
// 需求:复制照片
// 1.创建一个字节输入流管道与源文件接通
FileInputStream fis = new FileInputStream("C:\\Users\\63912\\Desktop\\源文件.txt");
// 2.创建一个字节输出流管道与目标文件接通
FileOutputStream fos = new FileOutputStream("D:\\pictures\\copy\\copy.txt");
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
fos.close();
fis.close();
System.out.println("复制完成!!");
}
}
既然是字节级操作,那么图片也是能复制的
释放资源的方式(两种)
什么时候需要释放资源?
后调用的先释放,先调用的后释放
try-catch-finally
- 之前我们释放资源的方式是有问题的,万一中间有什么异常,他就不会执行closed()方法,就不会释放资源