字符流
一. 输入流(Reader)
- 用于读取字符流的抽象类。
1. InputStreamReader(字符输入流)
① 概述
- 是从字节流到字符流的桥梁
- 它读取字节,并使用指定的编码将其解码为字符
- 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
② 构造方法
- InputStreamReader(InputStream in)
创建一个使用默认字符集的 InputStreamReader。 - InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的 InputStreamReader。
③ 常用方法
- int read()
读取单个字符。 - int read(char[] cbuf, int offset, int length)
将字符读入数组中的某一部分。
④ 注意事项
- 读取的文件和写入的文件的编码保持一致,就可以解决乱码的问题;
2. FileReader(字符文件输入流)
① 概述
- 继承自 InputStreamReader;
- 用来读取字符文件的便捷类。
- 此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。
② 构造方法
- FileReader(File file)
在给定从中读取数据的 File 的情况下创建一个新 FileReader。 - FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新 FileReader。
③ 常用方法
- int read()
读取单个字符。 - int read(char[] cbuf, int offset, int length)
将字符读入数组中的某一部分。
3. BufferedReader(字符缓冲输入流)
① 概述
- 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
- 可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
② 构造方法
- BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
③ 常用方法
- int read()
读取单个字符。 - int read(char[] cbuf, int off, int len)
将字符读入数组的某一部分。 - String readLine()
读取一个文本行。
二. 输出流(Writer)
- 写入字符流的抽象类。
1. OutputStreamWriter(字符输出流)
① 概述
- 是从字符流到字节流的桥梁
- 使用指定的编码将写入的字符编码为字节
- 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
② 构造方法
- OutputStreamWriter(OutputStream out)
创建使用默认字符编码的 OutputStreamWriter。 - OutputStreamWriter(OutputStream out, String charsetName)
创建使用指定字符集的 OutputStreamWriter。
③ 常用方法
- void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。 - void write(int c)
写入单个字符。 - void write(String str, int off, int len)
写入字符串的某一部分。 - void flush()
刷新该流的缓冲
2. FileWriter(字符文件输出流)
① 概述
- 继承自 OutputStreamWriter;
- 用来写入字符文件的便捷类。
- 此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。
② 构造方法
- FileWriter(File file)
根据给定的 File 对象构造一个 FileWriter 对象。 - FileWriter(String fileName)
根据给定的文件名构造一个 FileWriter 对象。 - FileWriter(String fileName, boolean append)
根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
③ 常用方法
- void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。 - void write(int c)
写入单个字符。 - void write(String str, int off, int len)
写入字符串的某一部分。 - void flush()
刷新该流的缓冲
3. BufferedWriter(字符缓冲输出流)
① 概述
- 将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入
- 可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
② 构造方法
- BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。
③ 常用方法
- void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。 - void write(int c)
写入单个字符。 - void write(String str, int off, int len)
写入字符串的某一部分。 - void flush()
刷新该流的缓冲 - void newLine()
写入一个行分隔符。
4. PrintWriter(字符打印流)
① 概述
- 向文本输出流打印对象的格式化表示形式。
- 此类实现在 PrintStream 中的所有 print 方法;
② 构造方法
- PrintWriter(String fileName)
创建具有指定文件名称且不带自动行刷新的新 PrintWriter。 - PrintWriter(Writer out, boolean autoFlush)
创建新 PrintWriter。
③ 常用方法
- void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。 - void write(int c)
写入单个字符。 - void write(String str, int off, int len)
写入字符串的某一部分。 - void flush()
刷新该流的缓冲 - void print(Object x)
打印 Object 。 - void println(Object x)
打印 Object ,然后终止该行。
④ 特点
- 自动换行
- 自动刷新
注意: 要实现这两个功能,必须要开启自动刷新,还必须调用println() printf() format()
三. 字符流小结
四. 案例练习
1. 字符流复制文件目录
public class Copy {
public static void main(String[] args) {
copyFile("day01/myFile", "day01/copy");
}
/*
复制文件或者目录的方法
支持单个文件, 单级目录或者多级目录
采用字节流, 不支持复制音视频及图片资源
*/
public static void copyFile(String srcFile, String desFile) {
// 校验参数
File src = new File(srcFile);
File des = new File(desFile);
if (!src.exists()) {
System.out.println("目标文件不存在!");
return;
}
if (!des.exists()) {
System.out.println("目的地文件不存在!");
return;
}
// 获取到src的目录结构
File[] files = src.listFiles();
if (files != null) { // 如果files 不为null, 则遍历该目录
// 创建目录
File file = new File(desFile + "/" + src.getName());
file.mkdir();
for (File f : files) {
if (f.isFile()) {// 是文件, 复制文件
copy(f.toString(), file.toString());
}else {// 是目录, 递归
copyFile(f.toString(), file.toString());
}
}
} else { // 如果files 为null, 则src 为文件 或者是 空目录
if (src.isFile()) {// src 是文件
copy(srcFile, desFile);
} else {// src是空目录
// 创建目录
File file = new File(desFile + "/" + src.getName());
file.mkdir();
}
}
}
// 复制单个文件方法
public static void copy(String src, String des) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
// 创建字符缓冲输入流, 指向需要被复制的文件
br = new BufferedReader(new FileReader(src));
// 创建字符缓冲输出流, 指向目的地文件
bw = new BufferedWriter(new FileWriter(des + "/" + new File(src).getName()));
// 读取文件, 一次读取一行
String line;
while ((line = br.readLine()) != null) {
// 写入文件, 一次写入一行
bw.write(line);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 释放资源
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Properties
1. 介绍
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
2. 构造方法
- Properties()
创建一个无默认值的空属性列表。
3. 特有方法
- Object setProperty(String key, String value)
设置集合的键和值,都是String类型,底层调用 Hashtable方法 put - String getProperty(String key)
使用此属性列表中指定的键搜索属性 - Set stringPropertyNames()
从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
4. 与IO流结合的方法
- void load(InputStream inStream)
从输入流中读取属性列表(键和元素对)。 - void load(Reader reader)
按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 - void store(OutputStream out, String comments)
以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 - void store(Writer writer, String comments)
以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。
5. 作用
- 用于简单的配置文件
- 创建文件时,扩展名为xxx.properties
6. 案例练习
- 读取配置信息, 修改配置信息
public class MyProperties {
public static void main(String[] args) throws IOException {
// 创建Properties集合对象
Properties pps = new Properties();
// 读取文件, 把name加载到pps中
pps.load(new InputStreamReader(new FileInputStream("day01/names.properties"),"GBK"));
// 输出配置信息
Set<Object> keys = pps.keySet();
for (Object key : keys) {
String value = pps.getProperty((String) key);
System.out.println(key + ":" + value);
}
// 修改配置信息
pps.setProperty("password", "root");
// 将修改的信息写入配置文件
pps.store(new OutputStreamWriter(new FileOutputStream("day01/names.properties"),"GBK"), "");
}
}