一.字符流概述
字符流是可以直接读写字符的IO流。
字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符,
需要把字符转为字节再写出.
本质:字节->字符 输出:字符->字节
字符流中的超类是Reader和Writer;(抽象类)
字符流的操作形式实际上与字节的操作形式非常的类似;
二. FileReader和FileWriter(字符输入输出流)
FileReader字符输入流的使用
注:FileReader一次读取最小一个字符
FileWriter的使用
注:FileWriter一次写入最小一个字符
说明:FileWriter类的write()方法可以自动把字符转为字节进行写操作
字符流的拷贝实现
FileReader fr = new
FileReader("a.txt");
FileWriter fw = new
FileWriter("b.txt");
int ch;
while((ch = fr.read())
!= -1) {
fw.write(ch);
}
fr.close();
fw.close();
字节流和字符流的区别和使用场景
区别
1. 字节流操作是以字节为单位,字符流是以字符为单位的;
2. 字节流没有使用到缓冲区,而是直接操作输出的,而字符流使用到了缓冲区,是通过缓冲区操作输出的。
使用场景
字符流也可以拷贝文本文件,但不推荐使用.因为读取时会把字节转为字符, 写出时还要把字符转回字节。
程序需要读取一段文本,或者需要写出一段文本的时候可以使用字符流,读取的时候是按照字符的大小读取的,不会出现半个中文;写出的时候可以直接将字符串写出,不用转换为字节数组;
因此如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点。
字符流是否可以拷贝非纯文本的文件?(比如:图片,视频)
不推荐拷贝非纯文本的文件;
因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去如果是?,直接写出,这样写出之后的文件就乱了。
三.字符缓冲流
字符缓冲流BufferedReader和BufferedWriter;
概述
BufferedReader的read()方法读取字符时会一次读取若干字符到缓冲区, 然后逐个返回给程序,
降低读取文件的次数, 提高效率;
BufferedWriter的write()方法写出字符时会先写到缓冲区,缓冲区写满时才会写到文件, 降低写文件的次数,
提高效率;
案例说明
//创建字符输入流对象,关联aaa.txt
BufferedReader br = new BufferedReader(new
FileReader("aaa.txt"));
//创建字符输出流对象,关联bbb.txt
BufferedWriter bw = new
BufferedWriter(new
FileWriter("bbb.txt"));
int
ch;
//read一次,会先将缓冲区读满,从缓冲去中一个一个的返给临时变量ch
while((ch = br.read())
!= -1) {
//write一次,是将数据装到字符数组,装满后再一起写出去
bw.write(ch);
}
br.close();
bw.close();
字符缓冲流的readLine()和newLine()方法
BufferedReader的readLine()方法可以读取一行字符(不包含换行符号)
BufferedWriter的newLine()可以输出一个跨平台的换行符
Windows的换行符是”\n\r” Linux的换行符”\n”
案例演示
BufferedReader br = new
BufferedReader(new FileReader("aaa.txt"));
BufferedWriter bw = new
BufferedWriter(new FileWriter("bbb.txt"));
String line;
while((line =
br.readLine()) != null) {
bw.write(line);
//bw.write("\r\n"); //只支持windows系统
bw.newLine(); //跨平台的
}
br.close();
bw.close();
思路: 将一个文本文档上的文本反转,第一行和倒数第一行交换,第二行和倒数第二行交换
Reader reader = new FileReader("1.txt");
BufferedReader br = new
BufferedReader(reader);
BufferedWriter bw = new
BufferedWriter(new FileWriter("2.txt"));
List list = new
ArrayList();
String len;
while((len =
br.readLine()) != null){
list.add(len);
}
for (int i = 0; i <
list.size(); i++) {
String str = list.get(i);
StringBuffer buffer = new
StringBuffer(str);
bw.write(buffer.reverse().toString());
bw.newLine();
}
br.close();
bw.close();
四. LineNumberReader
LineNumberReader是BufferedReader的子类, 具有相同的功能, 并且可以统计行号;
getLineNumber()方法可以获取当前行号
setLineNumber()方法可以设置当前行号
五. InputStreamReader和OutputStreamWriter(转换流)
转换流用于实现字节流和字符流的转换
FileReader是使用默认编码读取文件的,如果需要使用指定编码格式读取,那么可以使用
InputStreamReader(字节流,编码表)
FileWriter是使用默认编码写出文件,如果需要使用指定编码格式写出, 那么可以使用
OutputStreamWriter(字节流,编码表)
应用场景:当在操作流的时候需要指定编码格式的时候就使用转换流!
案例演示
//字节流-->字符流
BufferedReader br = new BufferedReader(new
InputStreamReader(new FileInputStream("UTF-8.txt"),
"UTF-8"));
//字符流-->字节流
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK"));
int ch;
while((ch = br.read()) != -1) {
bw.write(ch);
}
br.close();
bw.close();
转换流使用场景
如果读取或者写入的时候需要指定编码格式那么这时候就需要转换流来完成了。
六. PrintStream和PrintWriter(打印流)
打印流的主要功能是用于输出,在整个 IO 包中打印流分为两种类型:
• 字节打印流: PrintStream
• 字符打印流: PrintWriter
打印流在设计上成为"装饰设计模式"
PrintStream,PrintWriter,可以打印任何数据类型;
方法名:printf(String format,Object... args)
模板 描述
%s 表示字符串
%d 表示整数
%n.mf(例如:%7.2f) 表示小数
%c 表示字符
输入输出重定向
七. 内存操作流
概述
之前已经学习过了文件的操作流,输入输出都是从文件中进行的,那么如果现在希望产生一些临时的文件,但这些文件又不想在硬盘中直接生成,那么此时就可以使用内存输入、输出流完成。
内存输入流使用 ByteArrayInputStream,是 InputStream 的直接子类;
内存输出流使用 ByteArrayOutputStream,是 OutputStream 的直接子类;
特点
1. 在内存操作流中所有的输入和输出都是以内存为操作的源头;
2. ByteArrayInputStream 所有的内容都向内存中输出,但是对于内存而言属于数据的输入;
3. ByteArrayOutputStream 是用于从内存向程序输出的;
ByteArrayInputStream的构造方法
public ByteArrayInputStream(byte[] buf)
将内容输入到内存之中
ByteArrayOutputStream常用方法
public String toString();
取出全部的内容,由内存中取出
public byte[] toByteArray();
创建一个新分配的 byte
数组。其大小是此输出流的当前大小,并且缓冲区的有效内容已复制到该数组中。
注意:是关闭内存流无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException;
案例演示
FileInputStream fis = new
FileInputStream("a.txt");
ByteArrayOutputStream baos = new
ByteArrayOutputStream();
int b;
while((b = fis.read()) != -1) {
baos.write(b);
}
//byte[] newArr = baos.toByteArray();
//将内存缓冲区中所有的字节存储在newArr中
//System.out.println(new String(newArr));
System.out.println(baos);
fis.close();