File、IO流概述
File:代表文件
File是
java.io包下的类,File类的对象,用于代表当前操作系统的文件(可以是文件、或文件夹)。File类可以实现获取文件信息(大小、文件名、修改时间)、判断文件类型、创建文件/文件夹、删除文件/文件夹等操作
注意:File类只能对文件本身进行操作,不能读写文件里面存储的数据
IO流:读取文件
- 用于读写数据的(可以读写文件,或者网络中的数据…)
File
创建对象
File类对象构造方法:
构造方法 说明 public File(String pathname)根据文件路径创建文件对象 public File(String parent, String child)根据父路径和子路径名字创建文件对象 public File(File parent, String child)根据父路径对应文件对象和子路径名字创建文件对象 注意:
- File对象既可以代表文件,也可以代表文件夹。
- File封装的对象仅仅是一个路径名,这个路径可以是存在的,也允许是不存在的。
绝对路径、相对路径
- 绝对路径:从盘符开始。
- 相对路径:不带盘符,默认直接到当前工程下的目录寻求文件。
常用方法1:判断文件类型、获取文件信息
| 方法名称 | 说明 |
|---|---|
public boolean exists() |
判断当前文件对象,对应的文件路径是否存在,存在返回true |
public boolean isFile() |
判断当前文件对象指代的是否为文件,是则返回true,反之 |
public boolean isDirectory() |
判断当前文件对象指代的是否为文件夹,是则返回true,反之 |
public String getName() |
获取文件的名称(包含后缀) |
public long length() |
获取文件的大小,返回字节个数 |
public long lastModified() |
获取文件的最后修改时间 |
public String getPath() |
获取创建文件对象时,使用的路径 |
public String getAbsolutePath() |
获取绝对路径 |
常用方法2:创建文件、删除文件
File类创建文件的功能
方法名称 说明 public boolean createNewFile()创建一个新的空文件 public boolean mkdir()只能创建一级文件夹 public boolean mkdirs()可以创建多级文件夹 File类删除文件的功能
方法名称 说明 public boolean delete()删除文件、空文件夹 注意:
delete方法默认只能删除文件和空文件夹,删除后的文件不会进入回收站。
常用方法3:遍历文件夹
File类提供遍历文件夹的功能
方法名称 说明 public String[] list()获取当前目录下所有的“一级文件名称”到一个字符串数组中去返回 public File[] listFiles()获取当前目录下所有的“一级文件对象”到一个文件对象数组中去返回(重点) 使用
listFlies方法时的注意事项:- 当主调时文件,或者路径不存在时,返回null
- 当主调是空文件夹时,返回一个长度为0的数组
- 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
- 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
- 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null
前置知识:
方法递归
什么是方法递归?
- 递归是一种算法,在程序设计语言中广泛应用
- 从形式上说:方法调用自身的形式称为方法递归(recursion)
递归的形式
- 直接递归:方法自己调用自己
- 间接递归:方法调用其他方法,其他方法又回调方法自己
使用方法递归时需要注意的问题:
- 递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误
递归算法三要素:
- 递归公式
- 递归的终结点
- 递归的方向必须要走向终止点
其他应用:文件搜索
分析:
- 先找出该当前文件夹下的所有一级目录
- 遍历全部一级对象,判断是否是文件
- 如果是文件,判断是否是自己想要的
- 如果是文件夹,需要继续进入到该文件夹,重复上述过程
代码实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39import java.io.File;
public class SearchFile {
public static void main(String[] args) {
File f = new File("D:");
searchFile(f, "QQ");
}
/**
* @param dir 目录
* @param fileName 要搜索的文件名称
*/
public static void searchFile(File dir, String fileName){
// 1.拦截非法情况
if (!dir.exists() || dir.isFile() ||dir == null){
return;
}
// 2.获取该当前目录下所有一级目录
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.getAbsoluteFile());
}
}else {
searchFile(f, fileName);
}
}
}
}
}
字符集
常见字符集介绍
标准ASCII字符集
- ASCII(American Standard Code for Information Interchange):美国信息交换标准代码,包括英文、符号等。
- 标准ASCIII使用1个字节存储一个字符,首尾是0总共可以表示128个字符。
GBK(汉字内码扩展规范,国标)
- 汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储。
- 注意:GBK兼容了ASCII字符集
- GBK规定:汉字的第一个字节的第一位必须是1
Unicode字符集(统一码,也叫万国码)
- Unicode是国际组织制定的,可以容纳世界上所有文字、符号的字符集
UTF-32:四个字节表示一个字符,但由于占存储空间大、通信效率变低等原因,并没有被完全采纳
UTF-8
UTF-8是Unicode字符集的一种编码方案,采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节
UTF-8编码方式:
UTF-8编码方式(二进制) 0xxxxxxx: (ASCII码)110xxxxx10xxxxxx1110xxxx10xxxxxx10xxxxxx11110xxx10xxxxxx10xxxxxx10xxxxxx注意:技术人员在开发时都应该使用UTF-8编码
总结:
- ASCII字符集:只有英文、数字、符号等,占1个字节
- GBK字符集:汉字占2个字节,英文、数字占1个字节
- UTF-8字符集:汉字占3个字节,英文、数字占1个字节
- 注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
- 注意2:英文、数字一般不会出现乱码,英文很多字符集都兼容ASCII编码
字符集的编码、解码操作
Java代码完成对字符的编码
String提供了如下方法 说明 byte[] getBytes()使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中 byte[] getBytes(String charsetName)使用指定的字符集将String编码为一系列字节,将结果存储到新的字节数组中 Java代码完成对字符的解码
String提供了如下方法 说明 String(byte[] bytes)通过平台的默认字符集解码指定的字节数组来构造新的String String(byte[] bytes, String charsetName)通过指定的字符集解码指定的字节数组来构造新的String
IO流
IO流概述
IO流:输入输出流,读写数据的
I指Input,称为输入流:负责把数据读到内存中去O指Output,称为输出流:负责写数据出去
怎么学IO流:
- 先搞清楚IO流的分类、体系
- 再挨个学习每个IO流的作用、用法
IO流的分类:
按流的方向分为:
1
2
3graph TB;
IO流 --> 输入流
IO流 --> 输出流按流中数据的最小单位,分为:
1
2
3
4graph TB;
IO流 --> 字节流 --> 适合操作所有类型文件
IO流 --> 字符流 --> 只适合操作纯文本文件
IO流总体来看就有四大流:
- 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
- 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流
- 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流
- 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络中去的流
IO流的体系:
java.io包下:四大类流都是抽象类1
2
3
4
5
6
7graph TB;
IO流体系 --> 字节流
IO流体系 --> 字符流
字节流 --> 字节输入流\InpuStream --> FileInpuStream
字节流 --> 字节输出流\OutpuStream --> FileOutpuStream
字符流 --> 字符输入流\Reader --> FileReader
字符流 --> 字符输出流\Writer --> FileWriter
字节流
- 字节流非常适合做一切文件的复制操作:任何文件的底层都是字节,字节流做复制,是一字不漏的转移完全部字节,只要复制后的文件格式一致就没有问问题
FileInputStream
作用:以内存为基准,来自磁盘文件的数据以字节的形式读入到内存中去
构造方法:
构造方法 说明 public FileInputStream(File file)创建字节输入流管道与源文件接通 public FileInputStream(String pathname)创建字节输入流管道与源文件接通 常用方法:
方法名称 说明 public int read()每次读取一个字节返回,如果发现没有数据可读会返回-1 public int read(byte[] bytes)每次使用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1 注意事项:
- 使用
FileInputStream每次读取一个字节,读取性能较差,并且读取汉字输出会乱码 - 使用
FileInputStream每次读取多个字节,读取性能得到了提升,但读取汉字还是会输出会乱码
- 使用
一次读完读取完全部字节
方式一:定义一个与文件一样大的字节数组,一次性读取完文件的全部字节
方式二:Java官方为
InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。方法名称 说明 public byte[] readAllBytes() throws IOException直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回
读取文本内容更适合字符流,字节流适合做数据的转移,如:文件复印等
FileOutputStream
作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去
构造方法:
构造方法 说明 public FileOutStream(File file)创建字节输出流管道与源文件对象接通 public FileOutStream(String filepath)创建字节输出流管道与源文件对象接通 public FileOutStream(File file, boolean append)创建字节输出流管道与源文件对象接通,可追加数据 public FileOutStream(String filepath, boolean append)创建字节输出流管道与源文件对象接通,可追加数据 常用方法:
方法名称 说明 public void write(int a)写一个字节出去 public void write(byte[] buffer)写一个字节数组出去 public void write(byte[] buffer, int pos, int len)写一个字节数组的一部分出去 public void close() throws IOException关闭流
释放资源的方式
try-catch-finally1
2
3
4
5
6
7
8try{
...
...
} catch (IOException e){
e.prntStackTrace();
} fianlly{
}finally代码区的特点:不论try中的程序是否正常执行,最后一定会执行finally区,除非JVM终止。
作用:一般用于在程序执行完后进行资源的释放操作(专业级做法)。
try-with-resource:JDK7开始提供了更简单的资源释放方法1
2
3
4
5
6try(定义资源1, 定义资源2){
...
...
} catch (IOException e){
...
}注意:
- 该资源使用完毕后,会自动调用其
close()方法,完成对资源的释放! ()中只能放置资源对象(流对象)。- 实现接口
AutoCloseable的对象称之为资源对象,资源都会有一个close()方法
- 该资源使用完毕后,会自动调用其