一、File类
1.1 File对象的创建
1.1.1、public File(String pathname)
- 根据文件路径创建文件对象
• 示例: File file = new File("D:\\file\\map2\\Student.java");
1.1.2、public File(String parent, String child)
- 根据父路径和子路径名字创建文件对象
• 示例: File file = new File("D:\\file\\map2”,“Student.java");
1.1.3、public File(File parent, String child)
- 根据父路径文件对象和子路径名字创建文件对象
• 示例: File f = new File("D:\\file\\map2”);
File file = new File(f,“Student.java");
1.1.4、注意
- java中的路径"\"要写成"\\",也可以直接使用"/"
1.2 File判断和获取方法
1.2.1、 public boolean exists()
- 判断当前的文件对象,对应的文件路径是否存在,存在返回true
1.2.2、public boolean isFile()
- 判断当前文件对象指代的是否是文件,是文件返回true,不是返回false
1.2.3、public boolean isDirectory()
- 判断当前文件对象指代的是否是文件夹,是文件夹返回true,不是文件夹返回false
1.2.4、public String getName()
- 获取文件的名称(包含后缀)
• 示例:// 2: 获取文件的名字
System.out.println("文件的名字:"+file.getName());// 带后缀名
1.2.5、public long length()
- 获取文件的大小,返回字节个数
• 示例:// 1:获取字节数(只针对文件 不针对文件夹)
System.out.println("文件的字节数:"+file.length());//2258(字节)
1.2.6、public long lastModified()
- 获取文件的最后修改时间
• 示例://3: 获取文件的最后修改时间 long 毫秒值
long time = file.lastModified();
System.out.println("文件的最后修改时间:"+time);
//可以格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("文件修改时间:"+sdf.format(time));// 2023-08-09 08:55:53
1.2.7、public String getPath()
- 获取创建文件对象时,使用的路径
• 示例://4:getPath() 获取封装路径
System.out.println("文件的封装路径:"+file.getPath());
1.2.8、public String getAbsolutePath()
- 获取绝对路径
• 示例://5:getAbsolutePath() 获取绝对路径
System.out.println("文件的绝对路径:"+file.getAbsolutePath());
1.3 创建和删除方法
1.3.1、public boolean createNewFile()
- 创建一个新的空的文件
1.3.2、public boolean mkdir()
- 只能创建一级文件夹
1.3.3、public boolean mkdirs()
- 可以创建多级文件夹
1.3.4、public booelan delete()
- 删除文件、空文件夹
• 注意:delete方法默认只能删除文件和空文件夹,并且删除后的文件不会进入回收站
1.4 遍历文件夹方法
1.4.1、public String[] list()
- 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回
1.4.2、public File[] listFiles()
- 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回
1.4.3、注意事项
- 1、当主调是文件时,或者路径不存在时,返回null
- 2、当主调时空文件夹时,返回一个长度为0的数组
- 3、当主调是一个有内容的文件夹时,将里面所有的以及文件和文件夹路径放在File数组中,并把数组返回
- 4、当主调是一个文件夹,并且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中,包含隐藏文件
- 5、当主调是一个文件夹,但是没有访问权限时,赶回null
二、递归
2.1 递归算法引入
2.1.1、概念
- 递归是一种算法,从形式上说,方法调用自己的形式称之为递归
2.1.2、形式
- 直接递归、间接递归
• 示例:
public static void main(String[] args) {
test1();
}
// 直接方法递归
public static void test1(){
test1();
// 直接方法递归
}
// 间接方法递归
public static void test2(){
test3();
}
public static void test3(){
test2();
// 间接递归
}
• 注意:如果直接执行示例代码,会进入死循环,然后导致栈内存溢出StackOverflowError错误
2.2 递归算法的执行流程
// 计算n的阶乘
public static void main(String[] args) {
System.out.println("5的阶乘是:" + f(5));
}
//求n个数的阶乘
public static int f(int n){
// 终结点
if(n == 1){
return 1;
}else {
return f(n - 1) * n;
}
}
- 特点:一层一层调用,再一层一层往回返
2.3 递归文件搜索
案例:在`D:\\`判断下搜索QQ.exe这个文件,然后直接输出
- public static void main(String[] args) throws Exception {
- searchFile(new File("D:/") , "QQ.exe");
- }
- /**
- * 去目录下搜索某个文件
- * @param dir 目录
- * @param fileName 要搜索的文件名称
- */
- public static void searchFile(File dir, String fileName) throws Exception {
- // 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());
- Runtime runtime = Runtime.getRuntime();
- runtime.exec(f.getAbsolutePath());
- }
- }else {
- // 是文件夹,继续重复这个过程(递归)
- searchFile(f, fileName);
- }
- }
- }
- }
三、字符集
3.1 字符集的来历
3.1.1、美国人把他们用到的字符和字符对应的编码总结成了一张码表,这张码表叫做ASCII码表(也叫ASCII字符集)
3.1.2、编码:就是为一个字符编写一个二进制数据
3.1.3、GBK中一个汉字采用两个字节来存储,字母、数字还是用一个字节存储
3.2 Unicode字符集
3.2.1、三种编码方案
- UTF-32、UTF-16、UTF-8,其中比较常用的编码方案是UTF-8
3.2.2、UTF-8
- 1、UTF-8是一种可变长的编码方案,工分为4个长度区
- 2、英文字母、数字占1个字节(UTF-8兼容ASCII编码)
- 3、汉字字符占3个字节
- 4、极少数字符占4个字节
3.3 字符集小结
3.3.1、ASCII字符集
- 《美国信息交换标准代码》包含英文字母、数字、标点符号、控制字符
- 特点:1个字符占1个字节
3.3.2、GBK字符集
- 中国人自己的字符集,兼容ASCII字符集,还包含2万多个汉字
- 特点:1个字母占用1个字节,1个汉字占用2个字节
3.3.3、Unicode字符集
- 包含世界上所有国家的文字,有三种编码方案,最常用的是UTF-8
- UTF-8编码方案:英文字母、数字占1个字节兼容(ASCII编码)、汉字字符占3个字节
3.4 编码和解码
编码:把字符串按照指定的字符集转换为字节数组(把看得懂的变成看不懂的)
解码:把字节数组按照指定的字符集转换为字符串(把看不懂的变成看得懂的)
四、IO流(字节流)
4.1 IO流概述
输入流:把数据从磁盘、网络中读取到程序中来
输出流:把程序中的数据写入磁盘、网络中
IO流分为两大派系
- 1、字节流
• 字节输入流
• InputStream
• FileInputStream
• 字节输出流
• OutputStream
• FileOutputStream
- 2、字符流
• 字符输入流
• Reader
• FileReader
• 字符输出流
• Writer
• FileWriter
4.2 FileInputStream读取一个字节
4.2.1、字节输入流
- 用InputStream表示,但是InputStream是抽象类,所以使用的是它的子类FileInputStream
4.2.2、作用
- 以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去
4.2.3、构造方法
- 1、public FileInputStream(File file)
• 创建字节输入流管道与源文件接通
- 2、public FileInputStream(String pathname)
• 创建字节输入流管道与源文件接通
4.2.4、成员方法
- 1、public int read()
• 每次读取一个字节返回,如果发现没有数据可读会返回-1
- 2、public int read(byte[] buffer)
• 每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有可读会返回-1
4.2.5、使用FileInputStream读取文件中的字节数组,步骤如下
- 1、创建FileInputStream文件字节输入流管道,与源文件接通
- 2、调用read()方法开始读取文件的字节数据
• 示例:
public static void main(String[] args) throws Exception {
// 1、创建文件字节输入流管道,与源文件接通。
InputStream is = new FileInputStream(("D:\\file\\map2\\Student.java"));
// 2、开始读取文件的字节数据。
// public int read():每次读取一个字节返回,如果没有数据了,返回-1.
int b; // 用于记住读取的字节。
while ((b = is.read()) != -1){
System.out.print((char) b);
}
//3、流使用完毕之后,必须关闭!释放系统资源!
is.close();
}
- 3、调用close()方法释放资源
4.3 FileInputStream读取多个字节
4.3.1、使用FileInputStream一次读取多个字节步骤如下
- 1、创建FileInputStream文件字节输入流管道,与源文件接通
- 2、调用read(byte[] bytes)方法开始读取文件的字节数据
• 示例:public static void main(String[] args) throws Exception {
// 1、创建一个字节输入流对象代表字节输入流管道与源文件接通。
InputStream is = new FileInputStream("file-io-app\\src\\itheima02.txt");
// 2、开始读取文件中的字节数据:每次读取多个字节。
// public int read(byte b[]) throws IOException
// 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.
// 3、使用循环改造。
byte[] buffer = new byte[3];
int len; // 记住每次读取了多少个字节。
while ((len = is.read(buffer)) != -1){
// 注意:读取多少,倒出多少。
String rs = new String(buffer, 0 , len);
System.out.print(rs);
}
// 性能得到了明显的提升!!
// 这种方案也不能避免读取汉字输出乱码的问题!!
is.close(); // 关闭流
}
- 3、调用close()方法关闭管道,释放资源
4.3.2、注意:read(byte[] bytes)它的返回值,表示当前这一次读取的字节个数
4.4 FileInputStream读取全部字节
4.4.1、定义一个字节数组与被读取的文件大小一样大,让背后使用该字节数组,一次读完文件的全部字节
- public int read(byte[] buffer)
• 每次用一个字节数组去读取,返回字节数组独缺了多少字节,如果发现没有数据可读会返回-1
- 示例:
- // 1、一次性读取完文件的全部字节到一个字节数组中去。
- // 创建一个字节输入流管道与源文件接通
- InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
- // 2、准备一个字节数组,大小与文件的大小正好一样大。
- File f = new File("file-io-app\\src\\itheima03.txt");
- long size = f.length();
- byte[] buffer = new byte[(int) size];
- int len = is.read(buffer);
- System.out.println(new String(buffer));
- //3、关闭流
- is.close();
4.4.2、Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回
- public byte[] readAllBytes() throws IOException
• 直接将当前字节输入流对应的文件独享的字节数据装到一个一个字节数组返回
- 示例:
- // 1、一次性读取完文件的全部字节到一个字节数组中去。
- // 创建一个字节输入流管道与源文件接通
- InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
- //2、调用方法读取所有字节,返回一个存储所有字节的字节数组。
- byte[] buffer = is.readAllBytes();
- System.out.println(new String(buffer));
- //3、关闭流
- is.close();
- 注意:一次读取多有字节虽然可以解决乱码问题,但是文件不能过大,如果文件过大,可能导致内存溢出
4.5 FileOutputStream写字节
4.5.1、作用
- 以内存为基准,把内存中的数据以字节的形式写出到文件中去
4.5.2、使用FileOutputStream往文件写数据的步骤如下
- 1、创建FileOutputStream文件字节输出流管道,与目标文件接通
- 2、调用write()方法往文件中写数据
• 示例:
public static void main(String[] args) throws Exception {
// 1、创建一个字节输出流管道与目标文件接通。
// 覆盖管道:覆盖之前的数据
// OutputStream os = new FileOutputStream("file-io-app/src/itheima04out.txt");
// 追加数据的管道
OutputStream os = new FileOutputStream("file-io-app/src/itheima04out.txt", true);
// 2、开始写字节数据出去了
os.write(97); // 97就是一个字节,代表a
os.write('b'); // 'b'也是一个字节
// os.write('磊'); // 默认只能写出去一个字节
byte[] bytes = "我爱你中国abc".getBytes();
os.write(bytes);
os.write(bytes, 0, 15);
// 换行符
os.write("\r\n".getBytes());
os.close(); // 关闭流
}
- 3、调用close()方法关闭管道,释放资源
4.6 字节流复制文件
4.6.1 思路分析
- 1、创建一个FileInputStream流与源文件接通,创建FileOutputStream流与目标文件接通
- 2、然后创建一个数组,使用FileInputStream每次读取一个字节数组的数据,存入数组中
• 示例:public static void main(String[] args) throws Exception {
// 需求:复制照片。
// 1、创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("D:/resource/meinv.png");
// 2、创建一个字节输出流管道与目标文件接通。
OutputStream os = new FileOutputStream("C:/data/meinv.png");
System.out.println(10 / 0);
// 3、创建一个字节数组,负责转移字节数据。
byte[] buffer = new byte[1024]; // 1KB.
// 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
int len; // 记住每次读取了多少个字节。
while ((len = is.read(buffer)) != -1){ o
s.write(buffer, 0, len);
}
os.close();
is.close();
System.out.println("复制完成!!");
}
- 3、然后再使用FileOutputStream把字节数组中的有效元素,写入到目标文件中