IO流概述
IO流的概述和分类
输入流:把硬盘上的数据读取到内存中
- 字符输入流:读取字符
- 字节输入流:读取字节
输出流:把内存中的数据写入到硬盘中
-
字符输出流:写入字符
-
字节输出流:写入字节
字符流和字节流的区别
-
字节流读取的和写入都是字节;字符流读取的和写入的都是字符
-
使用字节流可以读写任意的文件,所有的数据(文本,音乐,视频,图片…),都是以字节的方式存储的
-
使用字节流读取的文件中若包含中文,因一次只读写一个字节(1/2 GBK,1/3 UTF-8 个中文),使用起来不方便,可能会出现乱码
-
使用字符流读取含有中文文本文件,一次读取一个字符(中文,英文,数字,符号…),使用起来很方便
什么时候使用字符流:读写文本文件(使用记事本打开能看懂)
什么时候使用字节流:读写非文本文件(图片,视频,音频…)
关闭和刷新的区别
-
flush:把内存缓冲区中的数据刷新到文件中,刷新完之后,流对象可以继续使用
-
close:释放资源(释放流相关的所有的系统资源和流对象),在释放资源之前,会把内存缓冲区中的数据刷新到文件中刷新完之后,流对象就已经关闭了,就不能在使用了
import java.io.FileWriter;
import java.io.IOException;
public class Demo02Writer {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("day21\\e.txt");
fw.write(66); // B
fw.flush(); // 把内存缓冲区中的数据刷新到文件中,刷新完之后,流对象可以继续使用
fw.write(67); // C
fw.close(); // 在释放资源之前,把内存缓冲区中的数据刷新到文件中,刷新完之后,流对象就已经关闭了,就不能在使用了
fw.write(68); // IOException: Stream closed
}
}
IO流的异常处理(JDK7后)
自动释放资源,不用再手动释放资源
格式:
try(
// 定义流对象
AAA aaa = new AAA();
BBB bbb = new BBB();
){
可能产生异常的代码
aaa.read();
bbb.write();
}catch(定义一个异常相关的变量,接收异常对象){
异常的处理逻辑
}
注意:
-
在 try 的后边增加一个(),在()中定义流对象那么这些流对象的作用域,就只在 try 中有效,执行完 try 中的代码,会自动释放流对象省略 finally
-
注意 try 后边的小括号中,不是任意对象都可以放,只有实现了 Closeable 接口的对象才能放
import java.io.*;
import java.util.Date;
public class Demo02JDK7After {
public static void main(String[] args) {
try(
//定义流对象
FileWriter fw = new FileWriter(new File("day21\\1.txt"), true);
){
for (int i = 1; i <= 10; i++) {
fw.write("你猜猜,我能写入到文件中吗?\r\n");
} catch(IOException e) {
e.printStackTrace();
}
try(
FileInputStream fis = new FileInputStream("c:\\2.jpg");
FileOutputStream fos = new FileOutputStream("d:\\2.jpg");
){
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1){
fos.write(bytes, 0, len);
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
字节流
InputStream:字节输入流超类
java.io.InputStream:字节输入流(此抽象类是表示字节输入流的所有类的超类)
InputStream 里边定义了所有字节输入流中共性的成员方法,所有的字节输入流都可以使用这些方法共性的成员方法:
int read() // 从输入流中读取数据的下一个字节。
int read(byte[] b) // 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
/* 1.read方法的参数byte[]字节数组的作用:
起到缓冲作用,把读取到的字节依次存储到数组中
把数组一次性的由操作系统返回JVM,由JVM返回给java程序,效率高
数组的长度一般都定义为1024或者1024的整数倍
2.read方法的返回值int是什么?
每次读取的有效字节个数。int=-1 表示读取结束。
*/
void close() // 关闭此输入流并释放与该流关联的所有系统资源。
OutputStream:字节输出流超类
java.io.OutputStream:字节输出流(此抽象类是表示输出字节流的所有类的超类)
OutputStream 里边定义了所有字节输出流中共性的成员方法,所有的字节输出流都可以使用共性的成员方法:
public void close() // 关闭此输出流并释放与此流相关联的任何系统资源。
public void flush() // 刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(int b) // 将指定的字节输出流。
public void write(byte[] b) // 将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) // 从指定的字节数组写入 len个字节,从偏移量 off开始输出到此输出流。
FileInputStream:文件字节输入流
java.io.FileInputStream extends InputStream
作用:把文件中的数据,以字节的方式读取到内存中
构造方法:
public FileInputStream(String name)
public FileInputStream(File file)
/* 参数:传递要读取的数据源
String name:要读取的数据源是一个文件的路径
File file:要读取的数据源是一个文件
*/
构造方法的作用:
1.会创建FileInputStream对象
2.会把创建好的FileInputStream对象,指向要读取文件的第一个字节
注意:使用构造方法创建对象,如果要读取的文件不存在,不会创建文件,会抛出文件找不到异常
使用字节输入流读取文件到内存中底层原理:
java程序 ==> JVM ==> 操作系统 ==> 调用系统中读取文件的方法 ==> 读取文件
使用示例
字节输入流的使用步骤:
1.创建FileInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,以字节的方式读取文件
3.释放资源
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
public class Demo01InputStream {
public static void main(String[] args) throws IOException {
/*
基本使用
*/
//1.创建FileInputStream对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("day21\\a.txt");
//2.使用FileInputStream对象中的方法read,以字节的方式读取文件
//int read() 从文件中一次读取一个字节并返回
/*
读取文件是一个重复的过程,所以可以使用循环优化
不知道文件中有多少字节,不知道循环多少次,使用while循环
循环结束的条件,read方法读取到-1的时候结束
循环中的布尔表达式:((len=fis.read()) != -1)
1.fis.read():读取文件中的一个字节
2.len = fis.read():把读取到的字节赋值给变量len
3.(len = fis.read()) != -1:判断变量len的值是否为-1
len不是-1就执行循环体,打印len(读取到的字节)
len是-1结束循环
*/
int len = 0;
while ((len=fis.read()) != -1){
System.out.print((char)len);
}
//3.释放资源
fis.close();
/*
使用字节输入流一次读取多个字节
*/
FileInputStream fis = new FileInputStream("day21\\b.txt");
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1){
//System.out.println(Arrays.toString(bytes));
//System.out.println(len);//5 读取的有效字节个数
System.out.println(new String(bytes, 0, len));
}
fis.close();
}
}
FileOutputStream:文件字节输出流
java.io.FileOutputStream extends OutputStream
作用:把内存中的字节写入到硬盘的文件中保存
构造方法:
public FileOutputStream(File file)
public FileOutputStream(String name)
/* 参数:输出的目的地
String name:输出的目的地就是一个文件路径
File file:输出的目的地就是一个文件
*/
// 字节输出流的续写和换行
public FileOutputStream(File file, boolean append)
public FileOutputStream(String name, boolean append)
/* 参数:File file|String name:写入数据的目的地
boolean append:续写的开关
true:可以续写,使用构造方法创建对象,文件名相同,不会创建新的文件覆盖之前同名的文件,会继续往文件的末尾写数据
false:不可以续写,使用构造方法创建对象,文件名相同,会创建一个新的空白文件覆盖之前同名的文件,在新的文件中写数据
换行:使用换行符号
Windows系统里,每行结尾是 回车+换行 ,即 \r\n
linux,Unix系统里,每行结尾只有 换行 ,即 \n
Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
*/
构造方法的作用:
1.会创建FileOutputStream对象
2.会根据构造方法中传递的文件路径|文件,创建一个新的空白文件
3.会把FileOutputStream对象,指向创建好的文件,就可以往文件中写数据了
使用字节输出流往文件中写输出的底层过程:
java程序 ==> JVM ==> 操作系统(OS) ==> 调用系统中写数据的方法 ==> 把数据写入到文件中
使用示例
字节输出流的基本使用:
1.创建FileOutputStream对象,构造方法绑定要输出的目的地
2.使用FileOutputStream对象中的方法write,把数据写入到文件中
3.释放资源(关闭此文件输出流并释放与此流有关的所有系统资源)
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class Demo01OutputStream {
public static void main(String[] args) throws IOException {
/*
基本使用
*/
//1.创建FileOutputStream对象,构造方法绑定要输出的目的地
FileOutputStream fos = new FileOutputStream("day20\\1.txt");
//2.使用FileOutputStream对象中的方法write,把数据写入到文件中
fos.write(97);
//3.释放资源(关闭此文件输出流并释放与此流有关的所有系统资源)
fos.close();
/*
字节输出流中写多个字节的方法
*/
FileOutputStream fos = new FileOutputStream(new File("day20\\2.txt"));
// public void write(byte[] b) 一次把字节数组中所有的字节写入到文件中
byte[] bytes = {65, 66, 67, 68, 69, 70};
fos.write(bytes); //ABCDEF
/*
public void write(byte[] b, int off, int len) 一次把字节数组的一部分写入到文件中
int off:数组的开始索引,从哪个索引开始写
int len:写的字节个数
*/
fos.write(bytes, 2, 3); //CDE
// 把字符串转换为字节数组,写入到文件中
byte[] bytes2 = "中国".getBytes();
//IDEA默认使用UTF-8编码,1个中文占用3个字节 [-28, -72, -83, -27, -101, -67]
System.out.println(Arrays.toString(bytes2));
fos.write(bytes2);//中国
fos.close();
/*
字节输出流的续写和换行
*/
FileOutputStream fos = new FileOutputStream("day20\\3.txt", true);
for (int i = 1; i <=10 ; i++) {
fos.write(("你好" + i + "\r\n").getBytes());
}
fos.close();
}
}
字符流
编码表
**编码:**把能看懂的文字,转换为看不懂的文字(字符 ==> 字节)
**解码:**把看不懂的文字,转换为能看懂的文字(字节 ==> 字符)
**编码表:**就是生活中的文字和计算机中文字的对应关系表
-
a ==> 97 ==> 01100001 ==> 存储到计算机中
-
中 ==> 20013 ==> 0010000000001011 ==> 存储到计算机中
常用的编码表:
-
ASCII字符集 :英文,数字,标点符号和计算机中文字的对应关系
0 ==> 48 A ==> 65 a ==> 97
-
ISO-8859-1字符集:拉丁码表
拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
- ISO-8859-1 使用单字节编码,兼容ASCII编码。不支持中文
-
GBxxx字符集:国标
GB 就是国标的意思,是为了显示中文而设计的一套字符集。兼容ASCII表
-
GB2312:简体中文码表。 7000多个简体汉字
-
GBK:目前操作系统默认中文码表(简体,繁体),存储一个中文使用2个字节,21003个汉字
-
GB18030:最新的中文码表。包含的文字最全(简体,繁体,少数民族,日韩文字)
-
-
Unicode字符集 :万国码
-
UTF-8:最常用的万国表,兼容所有国家的文字
编码规则:
- 128个US-ASCII字符,只需一个字节编码。
- 拉丁文等字符,需要二个字节编码。
- 大部分常用字(含中文),使用三个字节编码。
- 其他极少使用的Unicode辅助字符,使用四字节编码。
-
Reader:字符输入流超类
java.io.Reader:字符输入流(用于读取字符流的抽象类)
是所有字符输入流最顶层的父类,里边定义了所有字符输入流共性的成员方法,所有的字符输入流都可以使用共性的成员方法:
int read() // 读取单个字符。
int read(char[] cbuf) // 将字符读入数组。
void close() // 关闭该流并释放与之关联的所有资源。
Writer:字符输出流超类
java.io.Writer:字符输出流( 写入字符流的抽象类)
是所有字符输出流最顶层的父类,里边定义了所有字符输出流中共性的成员方法,所有字符输出流都可以使用共性的成员方法:
abstract void close() // 关闭此输出流并释放与此流相关联的任何系统资源
abstract void flush() // 刷新此输出流并强制任何缓冲的输出字符被写出
void write(int c) // 写出一个字符
void write(char[] cbuf) // 将 b.length字符从指定的字符数组写出此输出流
void write(char[] b, int off, int len) // 从指定的字符数组写出len字符,从偏移量off开始输出到此输出流
void write(String str) // 写出一个字符串
void write(String str, int off, int len) // 写入字符串的某一部分
InputStreamReader:字符转换输入流
java.io.InputStreamReader extends Reader
作用:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。
解码:字节==>字符
构造方法:
public InputStreamReader(InputStream in) // 创建一个使用默认字符集的 InputStreamReader
public InputStreamReader(InputStream in, String charsetName) // 创建使用指定字符集的 InputStreamReader
/* 参数:
InputStream in:传递字节输入流,可以传递InputStream的任意的子类对象(读取文件中的字节)
String charsetName:传递编码表名称,不区分大小写的可以传递GBK(gbk),UTF-8(utf-8)...,
不写默认使用IDEA设置的编码(UTF-8)
*/
继续自父类的共性成员方法:
int read() // 读取单个字符。
int read(char[] cbuf) // 将字符读入数组。
void close() // 关闭该流并释放与之关联的所有资源。
OutputStreamWriter:字符转换输出流
java.io.OutputStreamWriter extends Writer
作用:OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。
编码:字符 ==> 字节
构造方法:
public OutputStreamWriter(OutputStream out) // 创建使用默认字符编码的 OutputStreamWriter。
public OutputStreamWriter(OutputStream out, String charsetName) // 创建使用指定字符集的 OutputStreamWriter。
/* 参数:
OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象(把字符转换之后的字节写入到文件中)
String charsetName:传递编码表名称,不区分大小写的可以传递GBK(gbk),UTF-8(utf-8)...,
不写默认使用IDEA设置的编码(UTF-8)
*/
继承自父类共性的成员方法:
public abstract void close() // 关闭此输出流并释放与此流相关联的任何系统资源。
public abstract void flush() // 刷新此输出流并强制任何缓冲的输出字符被写出。
public void write(int c) // 写出一个字符。
public void write(char[] cbuf) // 将 b.length字符从指定的字符数组写出此输出流。
public abstract void write(char[] b, int off, int len) // 从指定的字符数组写出len字符,从偏移量off开始输出到此输出流
public void write(String str) // 写出一个字符串
public void write(String str, int off, int len) // 写入字符串的某一部分。
FileReader:文件字符输入流便捷类
java.io.FileReader extends InputStreamReader(转换流) extends Reader
作用:把文件中的数据以字符的方式读取到内存中
构造方法:
public FileReader(String fileName)
public FileReader(File file)
/* 参数:传递要读取的数据源
String fileName:数据源就是一个文件路径
File file:数据源就是一个文件
*/
使用示例
使用字符输入流读取文件的步骤
1.创建FileReader对象,构造方法中绑定要读取的数据源
2.使用FileReader对象中的方法read,以字符的方式读取文件
3.释放资源
Stirng类的构造方法:
public String(char[] value) // 把字符数组转换为字符串
public String(char[] value, int offset, int count) // 把字符数组的一部分转换为字符串
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo02Reader {
public static void main(String[] args) throws IOException {
/*
基本使用
*/
//1.创建FileReader对象,构造方法中绑定要读取的数据源
FileReader fr = new FileReader("day21\\c.txt");
//2.使用FileReader对象中的方法read,以字符的方式读取文件
//int read() 一次读取一个字符并返回
/*int len = 0;
while ((len = fr.read()) != -1){
System.out.print((char)len);
}*/
//int read(char[] cbuf) 使用数组缓冲一次读取多个字符
char[] chars = new char[1024];
int len =0;
while ((len = fr.read(chars)) != -1){
System.out.println(new String(chars, 0, len));
}
//3.释放资源
fr.close();
}
}
FileWriter:文件字符输出流便捷类
java.io.FileWriter extends OutputStreamWriter(转换流) extends Writer
作用:把内存中的数据,以字符的方式写入到文件中
构造方法:
public FileWriter(File file)
public FileWriter(String fileName)
/* 参数:传递写入的目的地
String fileName:目的地是一个文件的路径
File file:目的地是一个文件
*/
public FileWriter(String fileName, boolean append)
public FileWriter(File file, boolean append)
/* 参数:File file|String fileName:写入数据的目的地
boolean append:续写的开关
true:可以续写,使用构造方法创建对象,文件名相同,不会创建新的文件覆盖之前同名的文件,会继续往文件的末尾写数据
false:不可以续写,使用构造方法创建对象,文件名相同,会创建一个新的空白文件覆盖之前同名的文件,在新的文件中写数据
换行:使用换行符号
Windows系统里,每行结尾是 回车 + 换行 ,即 \r\n
linux,Unix系统里,每行结尾只有 换行 ,即 \n
Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一
*/
一个参数构造方法的作用:
1.会创建FileWriter对象
2.会根据构造方法中传递的文件|文件的路径,创建一个新的空白的文件
3.会把FileWriter对象,执向空白的文件
使用示例
使用字符输出流基本步骤:
1.创建FileWriter对象,构造方法中绑定要写入的目的地
2.使用FileWriter对象中的方法write,把数据写入到内存缓冲区中
3.使用FileWriter对象中的方法flush,把内存缓冲区中的数据刷新到文件中
4.释放资源(close方法会自动调用flush,把内存缓冲区中的数据刷新到文件中,再释放资源)
import java.io.FileWriter;
import java.io.IOException;
public class Demo01Writer {
public static void main(String[] args) throws IOException {
/*
基本使用
*/
// 1.创建FileWriter对象,构造方法中绑定要写入的目的地
FileWriter fw = new FileWriter("day21\\d.txt");
// 2.使用FileWriter对象中的方法write,把数据写入到内存缓冲区中
// void write(int c):写出一个字符
fw.write(100);
fw.write('中'); // 中
// void write(char[] cbuf) : 写字符数组中的多个字符
char[] chars = {'a','b','c','1','2','3','中','国','@','#'};
fw.write(chars); // abc123中国@#
// abstract void write(char[] b, int off, int len):写字符数组的一部分字符;off数组的开始索引,len写的字符个数
fw.write(chars, 6, 2); //中国
// void write(String str) :写出一个字符串
fw.write("到中午了,我们该吃饭了");
// void write(String str, int off, int len):写入字符串的某一部分。off字符串的开始索引,len写的字符个数
fw.write("到中午了,我们该吃饭了", 5, 6);//我们该吃饭了
// 3.使用FileWriter对象中的方法flush,把内存缓冲区中的数据刷新到文件中
//fw.flush();
// 4.释放资源(close方法会自动调用flush,把内存缓冲区中的数据刷新到文件中,再释放资源)
fw.close();
/*
字符输出流的续写和换行
*/
FileWriter fw = new FileWriter(new File("day21\\g.txt"), true);
for (int i = 1; i <= 10; i++) {
fw.write("hello" + i + "\r\n");
}
fw.close();
}
}
字符转换流和读写便捷类的区别
-
字符转换流 InputStreamReader 和 OutputStreamWriter 可以指定编码,缺省 ufs-8 编码
-
字符读写便捷类 FileReader 和 FileWriter 不能指定编码,默认 utf-8 编码
使用 FileReader 读取 GBK 编码的文件:会出现乱码,编码和解码不一致导致。
FileReader 只能读取默认编码(UTF-8 编码)的文件
- GBK:采用的双字节编码,一个中文占用2个字节
- UTF-8:采用多字节编码,一个中文占用3个字节
缓冲流
概述
文件字节流(FileInputStream、FileOutputStream)和文件字符流(FileReader、FileWriter)这些都是计算机与硬盘之间发生的I/O 操作,基于硬盘的读写相对比较慢,读写操作收到了硬盘读取速度的限制。为了能够提高读写速度,一定程度上绕过硬盘的限制,Java提供了一种缓冲流来实现。
缓冲字节流(BufferedInputStream、BufferedOutputStream)和缓冲字符流(BufferedReader、BufferedWriter)就是先把数据缓冲在内存里,在内存中去做 IO 操作。基于内存的 IO 操作比基于硬盘的 IO 操作快很多。
**缓冲流的基本原理:**在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统 IO 次数,从而提高读写的效率。
BufferedInputStream:字节缓冲输入流
java.io.BufferedInputStream extends InputStream
构造方法:
public BufferedInputStream(InputStream in) // 创建一个具有默认缓冲区大小的BufferedInputStream对象
public BufferedInputStream(InputStream in, int size) // 创建具有指定缓冲区大小的 BufferedInputStream对象
/*参数:
InputStream in:传递字节输入流,可以传递InputStream的任意子类对象
可以传递FileInputStream对象,缓冲流就会给FileInputStream对象增加一个缓冲区(字节数组)
提高FileInputStream读取文件的效率
int size:指定缓冲区的大小(数组的长度),不写使用默认值(KB)
private static int DEFAULT_BUFFER_SIZE = 8192;
继承自父类共性的成员方法:
int read() // 一次读取一个字节并返回
int read(byte[] b) // 使用数组缓冲,一次读取多个字节
void close() // 关闭此输入流并释放与该流关联的所有系统资源。
使用示例
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo01BufferedInputStream {
public static void main(String[] args) throws IOException {
try(
//1.创建BufferedInputStream对象,构造方法中传递FileInputStream对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day22\\1.txt"));
){
//2.使用BufferedInputStream对象中的方法read,以字节的方式读取文件
//int read(byte[] b) 使用数组缓冲,一次读取多个字节
byte[] bytes = new byte[1024];
int len = 0;
while ((len = bis.read(bytes)) ! =-1){
System.out.println(new String(bytes, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedOutputStream:字节缓冲输出流
java.io.BufferedOutputStream extends OutputStream
构造方法:
public BufferedOutputStream(OutputStream out) // 创建一个新的缓冲输出流,具有默认缓冲区大小
public BufferedOutputStream(OutputStream out, int size) // 创建一个新的缓冲输出流,具有指定缓冲区大小
/* 参数:
OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象
我们可以传递FileOutputStream对象,缓冲流就会给FileOutputStream对象增加一个缓冲区(字节数组)
提高FileOutputStream读取文件的效率
int size:指定缓冲区的大小(数组的长度),不写使用默认值
*/
继承自父类的共性成员方法:
public void close() // 关闭此输出流并释放与此流相关联的任何系统资源
public void flush() // 刷新此输出流并强制任何缓冲的输出字节被写出
public void write(byte[] b) // 将 b.length字节从指定的字节数组写入此输出流
public void write(byte[] b, int off, int len) // 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流
public abstract void write(int b) // 将指定的字节输出流
使用示例
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo02BufferedOutputStream {
public static void main(String[] args) throws IOException {
try(
//1.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day22\\2.txt"));
){
//2.使用BufferedOutputStream对象中的方法write,把数据写入到内存缓冲区中
bos.write("你好".getBytes());
//3.使用BufferedOutputStream对象中的方法flush,把内存缓冲区中数据刷新到文件
bos.flush();
//4.释放资源(会先调用flush方法刷新数据到文件)
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader:字符缓冲输入流
java.io.BufferedReader extends Reader
构造方法:
public BufferedReader(Reader in) // 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
public BufferedReader(Reader in, int sz) // 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
/* 参数:
Reader in:传递字符输入流,可以传递Reader的任意的子类对象
我们可以FileReader,缓冲流就会给FileReader增加一个缓冲区
提高FileReader读取文件的效率
int sz:指定缓冲区的大小(数组长度),不指定使用默认值
*/
继承自父类的共性成员方法:
int read() // 读取单个字符。
int read(char[] cbuf) // 将字符读入数组。
void close() // 关闭该流并释放与之关联的所有资源。
特有的成员方法:
String readLine() // 读取一个文本行。一次可以读取一行数据
/* 通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行(\r\n)。
返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
使用示例
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo04BufferedReader {
public static void main(String[] args) throws IOException {
try(
//1.创建BufferedReader对象,构造方法中传递FileReader对象
BufferedReader br = new BufferedReader(new FileReader("day22\\3.txt"));
){
//2.使用BufferedReader对象中的方法read|readLine,以字符的方式读取文件
//String readLine() 读取一个文本行。一次可以读取一行数据
//注意:读取的文件中有null,仅仅是一个字符串"null",不是默认值null
String line;
while ((line = br.readLine()) != null){
System.out.println(line); //你好1你好2你好3 不会读取每行结尾的回车换行符号(行的终止符号)
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedWriter:字符缓冲输出流
java.io.BufferedWriter extends Writer
构造方法:
public BufferedWriter(Writer out) // 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
public BufferedWriter(Writer out, int sz) // 创建一个使用给定大小输出缓冲区的新缓冲字符输出流
/* 参数:
Writer out:传递字符输出流,可以传递Writer的任意的子类对象
我们可以传FileWriter,缓冲流就会给FileWriter增加一个缓冲区
提高FileWriter写入文件的效率
int sz:指定缓冲区的大小(数组长度),不指定使用默认值
*/
继承自父类共性的成员方法:
abstract void close() // 关闭此输出流并释放与此流相关联的任何系统资源
abstract void flush() // 刷新此输出流并强制任何缓冲的输出字符被写出
void write(int c) // 写出一个字符
void write(char[] cbuf) // 将 b.length字符从指定的字符数组写出此输出流
abstract void write(char[] b, int off, int len) // 从指定的字符数组写出 len字符,从偏移量 off开始输出到此输出流
void write(String str) // 写出一个字符串
void write(String str, int off, int len) // 写入字符串的某一部分
特有的成员方法:
void newLine() // 写入一个行分隔符。写一个换行符号,根据系统不同,而写不同的换行符号
/* Windows系统里,每行结尾是 回车+换行 ,即 \r\n
linux,Unix系统里,每行结尾只有 换行 ,即 \n
Mac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
*/
使用示例
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Demo05BufferedWriter {
public static void main(String[] args) throws IOException {
try(
//1.创建BufferedWriter对象,构造方法中传递FileWriter对象
BufferedWriter bw = new BufferedWriter(new FileWriter("day22\\4.txt",true));
){
//2.使用BufferedWriter对象中的方法write,把数据写入到内存缓冲区中
for (int i = 1; i <= 10; i++) {
bw.write("你好"+i);
bw.newLine();//写换行
}
//3.使用BufferedWriter对象中的方法flush,把内存缓冲区中的数据刷新到文件中
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
打印流
概述、异同
虽然像 FileOutputStream、OutputStreamWriter 这些输出流可以输出信息,但是其会要求把数据先处理为字符串或字节数组,使用不便。为此在 Java IO 体系专门提供了两个打印流——PrintStream 字节打印流 、PrintWriter 字符打印流。二者均重载了print、println 等函数,方便开发者直接输出打印其它类型的数据
PrintStream 类和 PrintWriter 类的功能基本相同,PrintStream 能做的 PrintWriter 也都能实现,并且 PrintWriter 的功能更为强大。但由于 PrintWriter 出现的比较晚,较早的 System.out 使用的是 PrintStream 来实现的,所以为了兼容就没有废弃 PrintStream。
PrintStream 类和 PrintWriter 类最大的差别是:
- PrintStream 在输出字符,将字符转换为字节时采用的是系统默认的编码格式,这样当数据传输另一个平台,而另一个平台使用另外一个编码格式解码时就会出现问题,存在不可控因素。
- PrintWriter 可以在传入 Writer【OutputStreamWriter(OutputStream out, String charsetName)】时可由程序员指定字符转换为字节时的编码格式,兼容性和可控性会更好。
PrintStream:字节打印流
java.io.PrintStream extends OutputStream
特点:
-
PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
PrintStream流中有两个特有的方法:print,println
-
与其他输出流不同,PrintStream 永远不会抛出 IOException,创建对象的时候,传递路径不存在,可能会抛出文件找不到异常
-
PrintStream叫打印流,只负责输出(打印),不能读取
构造方法:
public PrintStream(File file) // 打印流的目的地是一个文件
public PrintStream(OutputStream out) // 打印流的目的地是一个字节输出流
public PrintStream(String fileName) // 打印流的目的地是一个文件路径
成员方法:
void close() // 关闭此输出流并释放与此流相关联的任何系统资源
void flush() // 刷新此输出流并强制任何缓冲的输出字节被写出
void write(byte[] b) // 将 b.length字节从指定的字节数组写入此输出流
void write(byte[] b, int off, int len) // 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流
void write(int b) // 将指定的字节输出流
自己特有的成员方法:
void print(Object x) // 可以写任意类型数据,不换行
void println(Object x) // 可以写任意类型的数据,换行
修改输出语句的目的地为打印流的目的地
使用System类中的方法setOut,修改输出语句的目的地(控制台)为打印流的目的地
static void setOut(PrintStream out) // 重新分配“标准”输出流。
作用:不让输出语句在控制台输出了,在打印流的目的地文件中输出
使用示例
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Demo01PrintStream {
public static void main(String[] args) throws FileNotFoundException {
/*
基本使用
*/
//1.创建PrintStream对象,构造方法中绑定要输出的目的地
PrintStream ps = new PrintStream("day22\\print1.txt");
//2.使用PrintStream对象中的方法write,print,println,把数据写入到文件中
//继承自父类OutputStream的共性的成员方法write:使用write写数据,查看的时候,会查询编码表
ps.write(97);//a
//自己特有的成员方法:print,println写数据,原样输出
ps.println(97);//97
ps.println('@');//@
ps.println(true);//true
ps.println(1.1);//1.1
ps.println("aaa");//aaa
//3.释放资源
ps.close();
//打印字符数组不是地址值,是数组中的元素 void println(char[] x) 打印字符数组(字符串底层就是字符数组)
char[] chars = {'a','b','c'};
System.out.println(chars);//abc
System.out.println("abc");//abc
/*
修改输出语句的目的地为打印流的目的地
*/
System.out.println("输出语句的目的地默认是在控制台输出!");
PrintStream ps = new PrintStream("day22\\print2.txt");
System.setOut(ps);//修改输出语句的目的地(控制台)为打印流的目的地
System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println("输出语句的目的地不是控制台了,是print2.txt文件中");
}
}
PrintWriter:字符打印流
java.io.PrintWriter extends Writer
构造方法:
public PrintWriter(Writer out)
public PrintWriter(Writer out, boolean autoFlush)
public PrintWriter(OutputStream out)
public PrintWriter(OutputStream out, boolean autoFlush)
public PrintWriter(String fileName)
public PrintWriter(String fileName, String charsetName)
public PrintWriter(File file)
public PrintWriter(File file, String charsetName)
成员方法:
public void close() // 关闭此输出流并释放与此流相关联的任何系统资源
public void flush() // 刷新此输出流并强制任何缓冲的输出字节被写出
public void write(int c)
public void write(char buf[])
public void write(char buf[], int off, int len)
public void write(String s)
public void write(String s, int off, int len)
public PrintWriter append(CharSequence csq)
public PrintWriter append(CharSequence csq, int start, int end)
public PrintWriter append(char c)
特有的成员方法:
public void print(Object x) // 可以写任意类型的数据,不换行
public void println(Object x) // 可以写任意类型的数据,换行
// 使用指定的格式字符串和参数将格式化的字符串写入到这个写入器的便捷方法。如果启用了自动刷新,则对该方法的调用将刷新输出缓冲区
public PrintWriter printf(String format, Object ... args)
使用示例
import java.io.*;
import java.util.Locale;
public class PrintWriterDemo {
public static void main(String[] args) {
String s = "Hello World";
try {
PrintWriter pw = new PrintWriter(System.out);
// %s 表示将在那里放置一个字符串,即s
pw.printf(Locale.UK, "This is a %s program", s);
// 换行
pw.println();
// %d 表示将放置一个整数,即100
pw.printf(Locale.UK, "This is a %s program with %d", s, 100);
pw.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
序列化流
ObjectOutputStream:对象的序列化流
java.io.ObjectOutputStream extends OutputStream
作用:把对象以流的方式写入到文件中保存
构造方法:
public ObjectOutputStream(OutputStream out) // 创建写入指定 OutputStream 的 ObjectOutputStream。
/* 参数:
OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象
*/
特有的成员方法:
void writeObject(Object obj) // 将指定的对象写入 ObjectOutputStream
ObjectInputStream:对象的反序列化流
java.io.ObjectInputStream extends InputStream
作用:把文件中保存的对象以流的方式读取出来使用
构造方法:
public ObjectInputStream(InputStream in) // 创建从指定 InputStream 读取的 ObjectInputStream。
/* 参数:
InputStream in:传递字节输入流,我们可以传递InputStream的任意子类对象
*/
特有的成员方法:
Object readObject() // 从 ObjectInputStream 读取对象
不能被序列化的情况
transient:瞬态关键字
被 transient 关键字修饰的变量不能被序列化
private transient int age;
oos.writeObject(new Person("小美女", 18)); // 不会把18写入到文件中
Object obj = ois.readObject(); // Person{name='小美女', age=0}
static:静态关键字
被static修饰的成员属于类,不属于某一个对象,被所有的对象所共享使用
被static修饰的成员,也不能序列化,序列化的是对象
private static int age;
oos.writeObject(new Person("小美女",18)); // 不会把18写入到文件中
Object obj = ois.readObject(); // Person{name='小美女', age=0}
可能抛出的异常
NotSerializableException
-
在进行序列化|反序列化时,抛出 NotSerializableException:没有序列化异常
-
实体类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
Serializable接口是一个标记型接口,类实现了 Serializable 接口,接口就会给类添加上一个标记。
当进行序列化和反序列化的时候,JVM会检查类上是否有标记,有则序列化反序列化成功,没有会抛出异常
实体类 ==> 添加上了标记 ==> 放心进行序列化和反序列化了 ==> 类做不做其他的用途没有影响
ClassNotFoundException
public final Object readObject() throws IOException, ClassNotFoundException
/* readObject方法声明抛出了两个异常对象
ClassNotFoundException:找不到class文件异常
*/
反序列化有两个前提:
- 类实现 Serializable 接口
- 类有对应的 class 文件(Person.class)
序列号冲突异常
可序列化类可以通过声明名为 “serialVersionUID” 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)
显式声明其自己的 serialVersionUID:
private static final long serialVersionUID = xxL;
在类中手动添加了一个序列号,无论类是否修改,序列号都是固定写死的常量值,值是不会改变的,也就不会抛出异常了
例如:
public final class MyString implements java.io.Serializable
private static final long serialVersionUID = -6849794470754667710L;
示例:
public class Person implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
public int age;
}
案例
文件复制(缓冲流)
import java.io.*;
@slf4j
public class Demo03CopyFile {
public static void main(String[] args) {
/*
字节缓冲流
*/
long s = System.currentTimeMillis();
try(
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\全球通史.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\全球通史.txt"));
){
//一读一写复制文件
byte[] bytes = new byte[1024 * 500];
int len = 0;
while ((len = bis.read(bytes)) != -1){
bos.write(bytes, 0, len); //写有效字节个数(最后一次读取不一定是1024个)
bos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
long e = System.currentTimeMillis();
log.info("复制文件共耗时:" + (e-s) + "毫秒");
/*
字符缓冲流
*/
try(
BufferedReader br = new BufferedReader(new FileReader("day22\\csb.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("day22\\出师表.txt"));
){
//一读一写复制文件
String line;
while ((line = br.readLine()) != null){
//5.把读取的每行数据,存储到ArrayList集合中
bw.write(s);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
转换文件编码
将 GBK 编码的文本文件,转换为 UTF-8 编码的文本文件。
基本步骤:
1.创建InputStreamReader对象,构造方法中传递FileInputStream对象和GBK编码名称
2.创建OutputStreamWriter对象,构造方法中传递FIleOutputStream对象和UTF-8编码名称
3.使用InputStreamReader对象中的方法read,读取GBK编码的文件
4.使用OutputStreamWriter对象中的方法write,把读取到的数据,以UTF-8编码,写入到内存缓冲区中
5.释放资源(会先调用flush方法刷新数据到文件中)
import java.io.*;
public class Demo04Test {
public static void main(String[] args) throws IOException {
try (
//1.创建InputStreamReader对象,构造方法中传递FileInputStream对象和指定的编码表名称
InputStreamReader isr = new InputStreamReader(new FileInputStream("day22\\utf-8.txt"),"GBK");
){
//2.创建OutputStreamWriter对象,构造方法中传递FIleOutputStream对象和UTF-8编码名称
//OutputStreamWriter osw = new OutputStreamWriter(
// new FileOutputStream("day22\\utf-82.txt"),"UTF-8");
//不写编码名称默认UTF-8
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day22\\utf-83.txt"));
FileWriter osw = new FileWriter("day22\\utf-84.txt");
//3.使用InputStreamReader对象中的方法read,读取GBK编码的文件
int len = 0;
while ((len = isr.read()) != -1){
//4.使用OutputStreamWriter对象中的方法write,把读取到的数据,以UTF-8编码,写入到内存缓冲区中
osw.write(len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
IO工具类
java.io.File
参考:https://www.runoob.com/java/java-file.html
描述:文件和目录路径名的抽象表示形式
常用静态变量:
// 与系统有关的路径分隔符。 windows中分号";",Linux中冒号":"
static String pathSeparator
static char pathSeparatorChar
// 与系统有关的默认名称(文件夹名称)分隔符。windows中右斜杠"\",Linux中左斜杠"/"
static String separator
static char separatorChar
构造方法:
public File(String pathname)
public File(String parent, String child)
public File(File parent, String child)
常用方法:
/* 判断功能 */
// 此File表示的文件或目录是否实际存在
boolean exists()
// 是否为目录(文件夹) // 需先判断路径是否实际存在
boolean isDirectory()
// 是否为文件 // 需先判断路径是否实际存在
boolean isFile()
// 测试此抽象路径名是否为绝对路径名
boolean isAbsolute()
// 测试此抽象路径名与给定对象是否相等
boolean equals(Object obj)
// 测试应用程序是否可以读取此抽象路径名表示的文件
boolean canRead()
// 测试应用程序是否可以修改此抽象路径名表示的文件
boolean canWrite()
/* 创建删除功能 */
// 当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。// 路径必须是存在的和有权访问的,否则会抛出异常。路径必须是存在的和有权访问的,否则会抛出异常。// 文件存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean createNewFile() throws IOException
// 创建单级文件夹 // 文件夹存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean mkdir()
// 即可以创建单级文件夹,又可以创建多级文件夹 // 文件夹存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean mkdirs()
// 删除文件或文件夹,不走回收站 // 路径不存在或者文件夹中有内容,不会删除,返回false
boolean delete()
/* 目录遍历 */
// 返回一个String数组,表示该File目录中的所有子文件或目录 // 路径必须是目录,否则会抛异常
String[] list()
// 返回一个File数组,表示该File目录中的所有的子文件或目录 // 路径必须是目录,否则会抛异常
File[] listFiles()
// 返回由此抽象路径名表示的文件或目录的名称(末尾部分)
String getName()
// 返回抽象路径名的绝对路径名字符串
String getAbsolutePath()
// 获取文件的大小,单位是字节
long length()
// 重新命名此抽象路径名表示的文件
boolean renameTo(File dest)
commons-io 工具包
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency
commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类
IOUtils 工具类
包路径:org.apache.commons.io.IOUtils;
处理输入 – 输出流。所有成员字段和方法都是静态的
链接:https://blog.csdn.net/l2580258/article/details/89227761
常用静态变量:
static String LINE_SEPARATOR; // 行分隔符
static String LINE_SEPARATOR_UNIX = "\n"; // Unix系统的行分隔符
static String LINE_SEPARATOR_WINDOWS = "\r\n"; // Windows系统的行分隔符
常用静态方法:
注:类中的所有处理InputStream的方法都带有内部的缓冲区,所以不需要再使用 BufferedReader
或者 BufferedInputStream
,默认的缓冲区大小为4K,不过也可以自定义它的大小。
// 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以下)
static int copy(Reader input, Writer output) // 字符流
static int copy(InputStream input, OutputStream output) // 字节流
static void copy(InputStream input, Writer output, Charset encoding)
// 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以上)
static long copyLarge(InputStream input, OutputStream output)
static long copyLarge(Reader input, Writer output)
// 从流中读取内容,并转换为String的list
static List<String> readLines(InputStream input)
static List<String> readLines(InputStream input, String encoding)
// input 的类型可以为 InputStream,Reader
// encoding 的类型可以为 Charset,String
// 把数据写入到输出流中
static void write(String data, OutputStream output)
static void write(String data, OutputStream output, String encoding)
// 把string的List写入到输出流中
static void writeLines(Collection<?> lines, String lineEnding, OutputStream output)
static void writeLines(Collection<?> lines, String lineEnding, OutputStream output, String encoding)
// data 的类型可以为 byte[],CharSequence,StringBuffer,String
// output 的类型可以为 OutputStream,Writer
// encoding 的类型可以为 Charset,String
// 无条件的关闭一个可被关闭的对象而不抛出任何异常。
// 重载支持关闭所有的InputStream、OutputStream、Reader和Writer。
static void closeQuietly(Closeable closeable)
// 比较两个Reader对象的内容是否相同,相同返回true,否则返回false
static boolean contentEquals(Reader input1, Reader input2)
static boolean contentEquals(InputStream input1, InputStream input2)
// 比较两个Reader对象的内容是否相同,忽略行结束符而比较内容
static boolean contentEqualsIgnoreEOL(Reader input1, Reader input2)
// 从InputStream中返回一个行迭代器。行迭代器将持有一个打开的InputStream的引用。迭代结束后,应当关闭stream来释放内部资源。
static LineIterator lineIterator(InputStream input, String encoding)
// input 的类型可以为 InputStream,Reader
// encoding 的类型可以为 Charset,String。传null则使用默认的
// 返回字符输入流缓冲流
static BufferedReader toBufferedReader(Reader reader)
static BufferedReader toBufferedReader(Reader reader, int size)
// 返回字节输入流缓冲流
static InputStream toInputStream(CharSequence input)
static InputStream toInputStream(CharSequence input, String encoding)
// 返回字符串
static String toString(Reader input)
static String toString(InputStream input, String encoding)
static String toString(URI uri)
static String toString(URI uri, Charset encoding)
static String toString(URL url, Charset encoding)
static String toString(URL url, String encoding)
// input 的类型可以为 InputStream,Reader,byte[]
FileUtils 工具类
包路径:org.apache.commons.io.FileUtils;
操作文件的工具类
常见工具类:
// 读取一个文件以字符串形式返回
static String readFileToString(File file)
static String readFileToString(File file, String encoding)
// 文件复制
static void copyFile(File srcFile, File destFile)
// 复制整个文件夹到另外一个地方
static void copyDirectory(File source, File destination)
// 复制整个文件夹到另外一个地方,过滤一些指定的文件(比如名字,修改时时间等等)
static void copyDirectory(File source, File destination, FileFilter filter)
// 把一个文件复制到一个文件夹中
static void copyFileToDirectory(File srcFile, File destDir)
// 文件夹复制
static void copyDirectoryToDirectory(File srcDir, File destDir)
// 使用指定的编码将CharSequence写入文件中
static void write(File file, CharSequence data)
// 将集合按行写入到文件中
static void writeLines(File file, Collection<?> lines)
// 把字符串写入到一个文件中
static void writeStringToFile(File file, String data)
// 返回一个File对象
static File getFile(String... names)
// 返回表示系统临时目录的File对象
static String getTempDirectory()
// 返回表示用户目录的File对象
static String getUserDirectory()
// 创建了一个迭代器,可以按行遍历给定的文件
static LineIterator lineIterator(File file)
// 返回目录内容的大小
static long sizeOfDirectory(File directory)
// 比较两个文件的内容,返回比较的结果
static boolean contentEquals(File file1, File file2)
// 递归的删除一个文件夹
static void deleteDirectory(File directory)
FilenameUtils 工具类
参考:https://www.cnblogs.com/xwb583312435/p/9014868.html
路径:org.apache.commons.io.FilenameUtils;
常用方法:
// 获取当前系统格式化路径
static String normalize(String filename)
// 获取当前系统无结尾分隔符的路径
static String normalizeNoEndSeparator(String filename)
// 合并目录和文件名为文件全路径
static String concat(String basePath, String fullFilenameToAdd)
// 获取文件名称,包含后缀
static String getName(String filename)
// 获取文件路径去除目录和后缀后的文件名
static String getBaseName(String filename)
// 获取文件的后缀
static String getExtension(String filename)
// 获取文件的完整目录(示例:/D:/aa/bb/cc/)
static String getFullPath(String filename)
// 获取文件的目录不包含结束符(示例:/D:/aa/bb/cc)
static String getFullPathNoEndSeparator(String filename)
// 获取去除前缀的路径(示例:D:/aa/bb/cc/)
static String getPath(String filename)
// 获取去除前缀并结尾去除分隔符的路径(示例:D:/aa/bb/cc)
static String getPathNoEndSeparator(String filename)
// 获取前缀
static String getPrefix(String filename)
// 获取最后一个.(文件名与拓展名的分隔符)的位置
static int indexOfExtension(String filename)
// 获取最后一个分隔符的位置
static int indexOfLastSeparator(String filename)
// 转换分隔符为当前系统分隔符
static String separatorsToSystem(String path)
// 转换分隔符为linux系统分隔符
static String separatorsToUnix(String path)
// 转换分隔符为windows系统分隔符
static String separatorsToWindows(String path)
// 判断文件路径是否相同
static boolean equals(String filename1, String filename2)
// 判断文件路径是否相同,格式化并大小写不敏感 // IOCase.INSENSITIVE
static boolean equals(String filename1, String filename2, boolean normalized, IOCase caseSensitivity)
// 判断文件路径是否相同,格式化并大小写敏感
static boolean equalsNormalized(String filename1, String filename2)
// 判断文件路径是否相同,不格式化,大小写敏感根据系统规则:windows:敏感;linux:不敏感
static boolean equalsOnSystem(String filename1, String filename2)
// 判断文件扩展名是否等于指定扩展名
static boolean isExtension(String filename, String extension)
// 判断文件扩展名是否包含在指定字符串数组中
static boolean isExtension(String filename, String[] extensions)
// 判断文件扩展名是否包含在指定集合中
static boolean isExtension(String filename, Collection<String> extensions)
// 判断文件扩展名是否和指定规则匹配,大小写敏感
static boolean wildcardMatch(String filename, String wildcardMatcher)
// 判断文件扩展名是否和指定规则匹配,大小写不敏感 // IOCase.INSENSITIVE
static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity)
// 判断文件扩展名是否和指定规则匹配,根据系统判断敏感型:windows:不敏感;linux:敏感
static boolean wildcardMatchOnSystem(String filename, String wildcardMatcher)
// 移除文件的扩展名
static String removeExtension(String filename)
// 判断目录下是否包含指定文件或目录
static boolean directoryContains(String canonicalParent, String canonicalChild)
拓展
Properties 集合
java.util.Properties extends Hashtable<k,v> implements Map<k,v>
-
Properties(属性) 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。
-
Properties 集合是一个唯一和 IO 流相结合的集合:
- 可以使用 Properties 集合中的方法 store(),把集合中的临时数据 持久化到 硬盘中存储(内存 ==> 硬盘)
- 可以使用 Properties 集合中的方法 load(),把硬盘文件中保存的键值对 读取到 内存中集合里边使用(硬盘 ==> 内存)
-
属性列表中每个键及其对应值都是一个字符串。
Properties 是一个双列集合,不需要写泛型,key 和 value 默认都是字符串String类型
常用方法:
Object setProperty(String key, String value) // 往Properties集合中添加键值对,相当于Map集合的put方法
String getProperty(String key) // 根据key获取value,相当于Map集合的get(key)方法
Set<String> stringPropertyNames() // 返回此属性列表中的键集,相当于Map集合的keySet方法
// 把集合中的临时数据,持久化到硬盘中存储(内存-->硬盘)
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
/* 方法的参数:
OutputStream out:传递字节输出流,不能写中文,会出现乱码,可以传递OutputStream的任意子类对象
Writer writer:传递字符输出流,能写中文,不会出现乱码,可以传递Writer的任意的子类对象
String comments:注释解释说明我们保存文件是做什么用的,一般传递""
注释不能写中文,默认使用Unicode编码,写中文会出现乱码
*/
// 把硬盘文件中保存的键值对,读取到内存中集合里边使用(硬盘-->内存)
void load(InputStream inStream) // 传递字节输入流,不能读取含有中文的文件,可以传递InputStream的任意子类对象
void load(Reader reader) // 传递字符输入流,可以读取含有中文的文件,可以传递Reader的任意子类对象
/* 注意:
1.在Properties集合的配置文件中,可以使用 # 进行注释,被注释的键值对不会被读取
2.在Properties集合的配置文件中,健和值之间可以使用 =,空格,冒号 等一些符号作为键与值的分割符号
3.在Properties集合的配置文件中,健和值默认都是String类型,不需要添加引号,否则会画蛇添足
*/
使用示例
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
public class Demo01Properties {
public static void main(String[] args) {
/*
基本使用:使用Properties集合存储数据,遍历集合获取集合中的元素
*/
Properties prop = new Properties();
//使用Properties集合中的方法setProperty往集合中添加键值对
prop.setProperty("迪丽热巴","168");
prop.setProperty("古力娜扎","165");
//使用Properties集合中的方法stringPropertyNames,获取集合中所有的key,把key存储到一个Set集合中返回
Set<String> set = prop.stringPropertyNames();
//遍历Set集合,获取Properties集合的每一个key
for (String key : set) {
//使用Properties集合中的方法getProperty根据key获取value
String value = prop.getProperty(key);
System.out.println(key + "=" + value);
}
/*
把集合中的临时数据,持久化到硬盘中存储(内存-->硬盘)
*/
/*FileOutputStream fos = new FileOutputStream("day21\\prop1.txt");
prop.store(fos, "save data");
fos.close();*/
// 如果对象只使用一次,可以使用匿名对象(会自动关闭)
prop.store(new FileOutputStream("day21\\prop1.txt"), "save data");
prop.store(new FileWriter("day21\\prop2.txt"), "save data");
// 一般存储键值对的文件,叫配置文件,文件的后缀名一般都使用.properties
prop.store(new FileWriter("day21\\prop.properties"), "save data");
/*
把硬盘文件中保存的键值对,读取到内存中集合里边使用(硬盘-->内存)
*/
Properties prop = new Properties();
// 使用Properties集合中的方法load,把硬盘文件中保存的键值对,读取到内存中集合里边使用
//prop.load(new FileInputStream("day21\\prop.properties"));
prop.load(new FileReader("day21\\prop.properties"));
// 遍历Properties集合
Set<String> set = prop.stringPropertyNames();
Iterator<String> it = set.iterator();
while (it.hasNext()){
String key = it.next();
String value = prop.getProperty(key);
System.out.println(key+"\t"+value);
}
}
}
prop.properties
#save data
#Fri Jul 10 14:51:47 CST 2020
赵丽颖 160
杨幂:172
#古力娜扎=165
"迪丽热巴"=168
#马尔扎哈=180
ResourceBundle 工具类
java.util.ResourceBundle:操作资源的工具类
作用:我们可以使用ResourceBundle类中的方法读取以 .properties 结尾的文件
注意:
-
ResourceBundle是一个抽象类,我们无法直接创建对象使用,我们可以使用ResourceBundle类中的静态方法获取ResourceBundle的子类对象
static ResourceBundle getBundle(String baseName) /* 参数: String baseName:传递以.properties结尾的文件名称 data.properties ==> 传递data */
-
以properties结尾的文件必须放在当前模块的src下边,否则获取对象找不到配置文件,会抛出异常
MissingResourceException: Can't find bundle for base name data, locale zh_CN
常用方法:
// 用于读取配置文件(存储的都是键值对)
String getString(String key) // 根据配置文件中key,读取配置文件中的value
/* 注意:
配置文件中的key和value不要使用中文
*/
使用示例
import java.util.ResourceBundle;
public class Demo02ResourceBundle {
public static void main(String[] args) {
//获取ResourceBundle对象
ResourceBundle bundle = ResourceBundle.getBundle("data");
//使用ResourceBundle对象中的方法getString,根据配置文件中key,读取配置文件中的value
String username = bundle.getString("username");
System.out.println(username);//jack
String password = bundle.getString("password");
System.out.println(password);//1234
String sex = bundle.getString("sex");
System.out.println(sex);//Å®(sex=女)
//String age = bundle.getString("年龄");//java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key 年龄
//System.out.println(age);
}
}
data.properties(放在src的下边)
username=jack
password=1234
sex=女
年龄=18
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112033.html