字符集、IO流(一)
一、File类
长久存储的方式
File类,它的就用来表示当前系统下的文件(也可以是文件夹)
1.1 File对象的创建
需求我们注意的是:路径中"“要写成”\“, 路径中”/"可以直接用
/*
目标: 辨析 相对路径 绝对路径
*/
public class FileDemo03 {
public static void main(String[] args) {
// 前提是我在day09 src 创建 xiaopeng.txt
//创建一个File对象 指代xiaopeng.txt的文件
// 第一种方式 找到文件的绝对路径 带盘符(根)的路径
// E:\414\secode\day09\src\xiaopeng.txt
File f1 = new File("E:\\secode\\day09\\src\\xiaopeng.txt");
System.out.println(f1);
System.out.println(f1.exists());
// 相对路径(注意) 经常写的是相对路径 不带盘符
// 相对 是 相对的当前 idea中project
// E:\414\secode\ day09\src\xiaopeng.txt
// 当前project 相对路径
File f2 = new File("day09\\src\\xiaopeng.txt");
System.out.println(f2);
System.out.println(f2.exists());
}
}
1.2 File判断和获取方法
创建File对象的时候,会传递一个文件路径过来。但是File对象封装的路径是存在还是不存在,是文件还是文件夹其实是不清楚的。好在File类提供了方法可以帮我们做判断。
/*
目标: 辨析 是否真实文件 辨析 File是文件还是文件夹
*/
public class FileDemo02 {
public static void main(String[] args) {
//1:创建一个File对象 指代某个具体的文件
File f1 = new File("E:\\414\\resource\\出师表.txt");
System.out.println(f1);
File f2 = new File("E:\\414\\resource\\厨师表.txt");
System.out.println(f2);
// 1:有一个判断方法 exists() 是否是真实文件
System.out.println("f1是真实的文件吗:"+f1.exists());//true
System.out.println("f2是真实的文件吗:"+f2.exists());//false
//如果存在 能不能知道该文件的大小--里面的字节数
//2: 获取文件大小 length()
System.out.println("f1文件大小:"+f1.length());
// 3:File类型 除了指代某个具体的文件 还可以指代文件夹
File d1 = new File("E:\\414\\resource");
System.out.println(d1);
// d1 是文件夹 f1 是文件
System.out.println("f1是不是文件呢:"+f1.isFile());//true
System.out.println("d1是不是文件呢:"+d1.isFile());//false
System.out.println("f1是不是文件夹呢:"+f1.isDirectory());//false
System.out.println("d1是不是文件夹呢:"+d1.isDirectory());//true
}
}
public class FileDemo04 {
public static void main(String[] args) {
// 创建一个File对象 表达 系统中某个文件
// E:\414\resource\出师表.txt
File file = new File("E:\\414\\resource\\出师表.txt");
//
// File file = new File("day09\\src\\xiaopeng.txt");
// 获取方法
// 1:获取字节数(只针对文件 不针对文件夹)
System.out.println("文件的字节数:"+file.length());//2258
// 2: 获取文件的名字
System.out.println("文件的名字:"+file.getName());// 带后缀名 出师表.txt
//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
//4:getPath() 获取封装路径
System.out.println("文件的封装路径:"+file.getPath());// E:\414\resource\出师表.txt
//5:getAbsolutePath() 获取绝对路径
System.out.println("文件的绝对路径:"+file.getAbsolutePath());
}
}
1.3 创建和删除方法
File类提供了创建和删除文件的方法
1.mkdir(): 只能创建单级文件夹、
2.mkdirs(): 才能创建多级文件夹
3.delete(): 文件可以直接删除,但是文件夹只能删除空的文件夹,文件夹有内容删除不了。
1.4 遍历文件夹方法
1.当主调是文件时,或者路径不存在时,返回null
2.当主调是空文件夹时,返回一个长度为0的数组
3.当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹路径放在File数组中,并把数组返回
4.当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在FIle数组中,包含隐藏文件
5.当主调是一个文件夹,但是没有权限访问时,返回null
2.3 递归文件搜索
在D:\\
判断下搜索QQ.exe这个文件,然后直接输出。
1.先调用文件夹的listFiles方法,获取文件夹的一级内容,得到一个数组
2.然后再遍历数组,获取数组中的File对象
3.因为File对象可能是文件也可能是文件夹,所以接下来就需要判断
判断File对象如果是文件,就获取文件名,如果文件名是`QQ.exe`则打印,否则不打印
判断File对象如果是文件夹,就递归执行1,2,3步骤
所以:把1,2,3步骤写成方法,递归调用即可。
/**
* 目标:掌握文件搜索的实现。
*/
public class RecursionTest3 {
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);
}
}
}
}
}
三、字符集
需要我们注意汉字和字母的编码特点:
- 如果是存储字母,采用1个字节来存储,一共8位,其中第1位是0
- 如果是存储汉字,采用2个字节来存储,一共16位,其中第1位是1
- 当读取文件中的字符时,通过识别读取到的第1位是0还是1来判断是字母还是汉字
- 如果读取到第1位是0,就认为是一个字母,此时往后读1个字节。
- 如果读取到第1位是1,就认为是一个汉字,此时往后读2个字节。
ASCII字符集:《美国信息交换标准代码》,包含英文字母、数字、标点符号、控制字符
特点:1个字符占1个字节
GBK字符集:中国人自己的字符集,兼容ASCII字符集,还包含2万多个汉字
特点:1个字母占用1个字节;1个汉字占用2个字节
Unicode字符集:包含世界上所有国家的文字,有三种编码方案,最常用的是UTF-8
UTF-8编码方案:英文字母、数字占1个字节兼容(ASCII编码)、汉字字符占3个字节
四、IO流(字节流)
4.1 IO流概述
4.2 FileInputStream读取一个字节
需要用到的方法如下图所示:有构造方法、成员方法
4.5 FileOutputStream写字节
使用FileOutputStream往文件中写数据的步骤如下:
第一步:创建FileOutputStream文件字节输出流管道,与目标文件接通。
第二步:调用wirte()方法往文件中写数据
第三步:调用close()方法释放资源
4.6 字节流复制文件
1.需要创建一个FileInputStream流与源文件接通,创建FileOutputStream与目标文件接通
2.然后创建一个数组,使用FileInputStream每次读取一个字节数组的数据,存如数组中
3.然后再使用FileOutputStream把字节数组中的有效元素,写入到目标文件中
/**
* 目标:使用字节流完成对文件的复制操作。
*/
public class CopyTest5 {
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){
os.write(buffer, 0, len);
}
os.close();
is.close();
System.out.println("复制完成!!");
}
}