------- android培训、java培训、期待与您交流! ----------
字符流
1. 什么是字符流
字符流是专门用来操作字符数据的,读取字符数据会自动解码和编码
2. 所有字符输入流都是Reader的子类,所有字符输出流都是Writer的子类
3. 字符流和字节流的方法几乎一致,只不过一个操作的是字符数据, 一个操作的是字节数据,方法参见字节流
InputStreamReader类和OutputStreamWriter类
1. InputStreamReader可以把InputStream转换为字符流,从而读到字符
2. OutputStreamWriter将OutputStream转换为字符流,从而写出字符
3. 在读写字符时,字符流可以自动编码和解码
4. 如果不指定字符流的码表,用的是默认的码表, 中文简体操作系统默认的码表是GBK,可以通过InputStreamReader和OutputStreamWriter的构造方法指定输入和输出的码表
5. 字符流细节
读取文件字节-------à转成字符-------à读入程序
程序写出字符-------à转为字节-------à写到文件
代码示例(拷贝字符文件)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Demo1 {
public static void main(String[] args) throws IOException {
// 自动关闭流
try (
// 创建一个读入字符的对象, 将字节流数据转换为字符流
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"test.txt"));
// 创建一个写出字符的对象, 将字符流数据转换为字节流
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("test_copy.txt"));) {
int x; // 用来存储读取的单个字符
// 循环将每一个字符拷贝
while ((x = isr.read()) != -1) {
// 将读出的每个字符写进目标对象
osw.write(x);
}
}
}
}
FileReader类和FileWriter类
1. 这两个类简化了InputStreamReader类和OutputStreamWriter类,但是不能指定字符流码表
例如: FileReader fr = new FileReader(“test.txt”)就相当于
InputStreamReader isr = new InputStreamReader(newFileInputStream(“test.txt”));
代码示例(拷贝字符文件)
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo2 {
public static void main(String[] args) throws IOException {
try (
// 创建读入和写出的字符流对象
FileReader fr = new FileReader("test.txt");
FileWriter fw = new FileWriter("test_copy2.txt");) {
int x; // 用来保存单个字符数据
// 循环将每个字符拷贝到目标文件
while ((x = fr.read()) != -1) {
fw.write(x);
}
}
}
}
BufferedReader类和BufferedWriter类
1. 这两个类跟字节流的BufferedInputStream和BufferedOutputStream类很相似,一次读写最写8192个字符存入缓冲区,这样读写的效率比较高
2. 特有方法
BufferedReader中的rederLine()方法一次会读取一行字符数据,不包含换行返回String类型
BufferedWriter中的newLine()方法用于在写出数据时换行
代码示例
import java.io.*;
public class Demo3 {
public static void main(String[] args) throws FileNotFoundException,
IOException {
try (
// 创建输入流字符缓冲区对象
BufferedReader br = new BufferedReader(new FileReader("test.txt"));
// 创建输出流字符缓冲区, 将字符编码转换为utf-8输出
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("test_copy3.txt"), "utf-8"));) {
String s; // 用来存储一行的字符数据
// 循环将字符文件拷贝到目标文件
while ((s = br.readLine()) != null) {
// 写出读入的一行数据
bw.write(s);
// 写出换行
bw.newLine();
}
}
}
}
LineNunberReader类
1. 这个类能够读出当前字符流的行号,是BufferedReader的子类,这个类重写了父类的readLine()方法,用于读出行号
代码示例
import java.io.*;
public class Demo5 {
public static void main(String[] args) throws FileNotFoundException,
IOException {
try (
// 创建一个字符输入和输出流对象
LineNumberReader br = new LineNumberReader(new FileReader("test.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter(
"test_copy5.txt"))) {
// 拷贝字符文件
String s;
while ((s = br.readLine()) != null) {
bw.write(br.getLineNumber() + " " + s);
bw.newLine();
}
}
}
}
如何选择字符输入流对象
1. 只是需要默认码表用FIleReader和FileWriter
2. 使用非默认码表用InputStreamReader和OutputStreamWriter
3. 要效率高或读取一行用BufferedReader和BufferedWriter
装饰设计模式
1. 将一个类进行包装,实现更多的功能
2. 装饰设计模式的写法
1) 通过构造函数接收一个被包装对象
2)用成员变量引用
3)具有和被包装对象相同的方法
4)调用原对象的方法,进行功能增强
5)实现和被包装对象相同的接口,可以和被包装对象一样使用, 但功能已经增强了
代码示例
package com.itcast.rw;
public class DecoratorMode {
public static void main(String[] args) {
// 创建一个包装类的对象将要被包装的对象当做参数传入
ItcastStudent is = new ItcastStudent(new Student());
// 调用包装类的code方法
is.code(); // 这个方法多了两个功能
}
}
// 定义一个接口
interface Coder {
void code();
}
// 定义学生类实现Coder接口
class Student implements Coder {
/*
* 实现接口中的方法 学生有的功能是会JavaSE和Java Web
*/
public void code() {
System.out.println("JavaSE");
System.out.println("Java Web");
}
}
// 定义装饰类实现Coder接口
class ItcastStudent implements Coder {
// 这个类有一个Coder类型的成员属性
Coder coder;
/*
* 这个类的构造方法接收一个Student对象
*/
ItcastStudent(Coder coder) {
this.coder = coder;
}
/*
* 重写接口中的方法对传入构造方法的对象的功能进行扩展
*/
public void code() {
this.coder.code();
System.out.println("SSH");
System.out.println("Hadop");
}
}