【笔记】Java的文件和目录操作

前言

Java通过IO流实现对文件和目录的操作以及文件的读写

文件对象

  • 封装一个磁盘路径字符串

字符串

文件路径
文件夹路径
不存在路径

  • 提供对文件或文件夹的一些操作方法

创建对象

  • 不管文件是否存在,都会新建空文件
  • 如果目录不存在,会出异常

一个参数

<directory>:目录名
<file>:文件名

1
File file = new File("<directory>/<file>");

两个参数

1
File file = new File("<directory>", "<file>");

方法

文件或文件夹属性

获取文件大小
  • 获取文件的字节量
  • 对目录无效
1
length()
获取文件名
1
getName()
获取父目录
1
getParent()
获取最后修改时间
  • 毫秒值
1
getLastModified()
判断是否是文件
1
isFile()
判断是否是目录
1
isDirectory()
判断是否存在
1
exists()

新建文件

  • 如果文件已存在,则不新建,返回false
  • 如果父目录不存在,会出现异常
1
createNewFile()

新建目录

  • 创建单层目录
1
mkdir()
创建多层目录
1
mkdirs()

删除文件或空目录

  • 删除成功返回true,删除失败返回false
1
delete()

目录列表

  • 获得String[]数组,存放文件、目录名
1
list()
  • 获得File[]数组,存放文件、目录的封装对象
1
listFiles()
  • 对文件、不存在的路径、无权进入的目录,列表方法返回null

IO流

  • 抽象成数据在管道中流动
  • 单方向

输入流,只能用来读取数据
输出流,只能用来输出数据

  • 数据只能从头到尾顺序流动一次

字节流

字节读取流(输入流)

InputStream
  • 父类为抽象类,不能创建对象
  • 字节流可以处理任何数据的文件
FileInputStream
  • 子类继承父类,可以创建对象
  • 是一个字节一个字节的读取
创建对象

<str>:字符串类型的文件路径

1
InputStream in = new FileInputStream(<str>);

<file>:封装文件路径的File对象

1
InputStream fin = new FileInputStream(<file>);
读取
1
2
3
4
5
6
7
8
9
10
11
public static void FIS() throws IOException {
// 1. 创建对象
InputStream fin = new FileInputStream("~/Downloads/1.txt");
// 2. 开始读取
int b = 0;
while ((b=fin.read()) != -1) {
System.out.println(b);
}
// 3. 释放资源
fin.close();
}
BufferedInputStream
  • 子类继承父类,可以创建对象
  • 是一个数组一个数组的读取
  • 缓冲数组长度默认为8192
创建对象
  • 可以将任何InputStream子类作为对象传入参数
1
2
InputStream fin = new FileInputStream(<file>);
InputStream bis = new BufferedInputStream(fin);

<len>:直接给定数组长度

1
2
InputStream fin = new FileInputStream(<file>);
InputStream bis = new BufferedInputStream(fin, <len>);
读取
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void BIS() throws IOException {
// 1. 创建对象
InputStream fin = new FileInputStream("~/Downloads/1.txt");
InputStream bis = new BufferedInputStream(fin);
// 2. 开始读取
int b = 0;
while ((b=bis.read()) != -1) {
System.out.println(b);
}
// 3. 释放资源
fin.close();
bis.close();
}

字节写出流(输出流)

OutputStream
  • 父类为抽象类,不能创建对象
  • 字节流可以处理任何数据的文件
FileOutputStream
  • 子类继承父类,可以创建对象
  • 是一个字节一个字节的写出
创建对象
  • 默认数据覆盖模式
1
2
OutputStream fos = new FileOutputStream(<str>);
OutputStream fos = new FileOutputStream(<file>);
  • 数据追加模式
1
OutputStream fos = new FileOutputStream(<str>, true);
写出

<char>:需要写入的字符

1
fos.write(<char>);
BufferedOutputStream
  • 子类继承父类,可以创建对象
  • 是一个数组一个数组的写出
  • 缓冲数组长度默认为8192
创建对象
  • 默认数据覆盖模式
1
2
OutputStream fos = new FileOutputStream(<str>);
OutputStream bos = new BufferedOutputStream(fos);
1
2
OutputStream fos = new FileOutputStream(<str>);
OutputStream bos = new BufferedOutputStream(fos, <len>);
  • 数据追加模式
1
2
OutputStream fos = new FileOutputStream(<str>);
OutputStream bos = new BufferedOutputStream(fos, <len>, true);
写出
1
bos.write(<char>);

字符流

字符读取流(输入流)

Reader
  • 父类为抽象类,不能创建对象
  • 字符流只能处理文本数据的文件
FileReader
  • 子类继承父类,可以创建对象
  • 是一个字节一个字节的读取
创建对象
1
Reader fr = new FileReader(<str>);
1
Reader fr = new FileReader(<file>);
读取
1
fr.read();
BufferedReader
  • 子类继承父类,可以创建对象
  • 是一个数组一个数组的读取
  • 缓冲数组长度默认为8192
1
2
Reader fr = new FileReader(<str>);
Reader br = new BufferedReader(fr);
1
2
Reader fr = new FileReader(<str>);
Reader br = new BufferedReader(fr);
读取
1
br.read();
创建对象

字符写出流(输出流)

Writer
  • 父类为抽象类,不能创建对象
  • 字符流只能处理文本数据的文件
FileWriter
  • 子类继承父类,可以创建对象
  • 是一个字节一个字节的写出
创建对象
  • 默认数据覆盖模式
1
Writer fw = new FileWriter(<str>);
1
Writer fw = new FileWriter(<file>);
  • 数据追加模式
1
Writer fw = new FileWriter(<str>, true);
写出

<char>:可以写出任何类型数据,例如字符串

1
fw.writer(<char>);
BufferedWriter
  • 子类继承父类,可以创建对象
  • 是一个数组一个数组的写出
  • 缓冲数组长度默认为8192
创建对象
  • 默认数据覆盖模式
1
2
Writer fw = new FileWriter(<str>);
Writer bw = new BufferedWriter(fw);
  • 数据追加模式
1
2
Writer fw = new FileWriter(<str>, true);
Writer bw = new BufferedWriter(fw);
写出
1
bw.writer(<char>);

释放资源

<io>:输入或输出流对象

1
2
3
4
5
6
7
8
9
10
11
try {
...
} catch (IOException e) {
...
} finally {
try {
<io>.close();
} catch (IOException e) {
...
}
}

释放资源工具类

1
2
3
4
5
6
7
public static void close(Closeable c) {
try {
...
} catch (IOException e) {
...
}
}

try with resource

  • jdk1.7对于IO自动资源管理的优化
  • 将创建流的代码作为try的参数传入,实现自动释放资源
1
2
3
4
5
6
7
8
9
try (
//0,创建读取流和写出流--字节流/高级流/普通流/字符流
InputStream in = new BufferedInputStream( new FileInputStream(from) );
OutputStream out = new BufferedOutputStream( new FileOutputStream(to) );
) {
...
} catch (IOException e) {
...
}

文件复制

单字节读写
1
2
3
4
5
6
7
8
private static void copy(File from, File to) {
FileInputStream in = new FileInputStream(from);
FileOutputStream out = new FileOutputStream(to);
int b;
while((b = in.read()) != -1) {
out.write(b);
}
}
批量数据读写
1
2
3
4
5
6
7
8
9
private static void copy(File from, File to) {
FileInputStream in = new FileInputStream(from);
FileOutputStream out = new FileOutputStream(to);
byte[] buff = new byte[8192]; // 8k长度的数组
int n; // 用来保存一批的数量
while((n = in.read(buff)) != -1) {
write(buff, 0, n);
}
}

ObjectInputStream/ObjectOutputStream

  • 对象的序列化、反序列化

  • 把对象的信息,按照固定的字节格式,转成一串字节序列,输出

  • 被序列化的对象,必须实现Serializable借口

序列化输出对象

1
writeObject(Object obj)

反序列化恢复对象

1
readObject(Object obj)

Serializable接口

  • 空接口
  • 标识接口,标识一个类,可以被序列化

不序列化成员

  • static

静态属于类,不随对象一起被序列化输出

  • transient

只在程序运行期间,在内从中临时存在,不随对象一起被序列化持久保存

序列化版本

  • 控制旧版本数据,不允许恢复成新版本的类型
1
static final long serialVersionUID
  • 自己不定义,编译器会添加默认版本id

根据类的定义信息,计算产生一个id值

字符集、字符编码

ASC-II

  • 范围:0~127
  • 英文字符、标点、指令字符

iso-8859-1(Latin-1)

  • 范围:0~255
  • 西欧字符

cjk字符集

  • 中国、日本、韩国字符集统称

GBK

  • 中国国标码
  • 双字节编码
  • 包含21003个中文字符

Unicode编码

  • 统一码(万国码)
  • 有100万以上编码位
  • 常用字符表(双字节)
  • 生僻字符表(三字节或以上)

Unicode中文字符

  • 范围:\u4e00\u9fa5
  • 个数:20902个

UTF-8(Unicode Transfermation Format)

  • Unicode的传输格式
  • 英文(单字节)
  • 某些字符(双字节)
  • 中文(三字节)
  • 特殊符号(四字节)

Java的字符编码转换

Unicode转其他编码

  • 转成系统默认编码
1
getBytes()
  • 转成指定编码
1
getBytes("UTF-8")

其他编码转Unicode

  • 把系统默认的一组字节值,转成Unicode
1
new String(byte[])
  • 把指定编码的一组字节值,转成Unicode
1
new String(byte[], "UTF-8")

Reader/Writer

  • 字符流的抽象父类

方法

一个int参数

  • int四个字节中,末尾两个字节是char类型字符数据,只处理末尾两个字节的输出
1
write(int c)

三个参数

  • 输出from开始的length个字符
1
write(char[], from, length)

一个String参数

  • 输出字符串的全部字符
1
write(String s)

InputStreamReader/OutputStreamWriter

  • 字符编码转换流

InputStreamReader

  • 读取其他编码转成Unicode

OutputStreamWriter

  • 把Unicode转成其他编码输出

<path>:文件路径

1
2
new OutputStreamWriter(new FileOutputStream("<path>")
new OutputStreamWriter(new FileOutputStream("<path>"), "UTF-8")

完成