5 字符流
5.1 为什么出现字符流
- 由于字节流操作中文不是特别的方便,所以Java就提供字符流
- 字符流=字节流+编码表
- 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
- 汉字在存储的时候, 无论选择哪种编码存储,第一个字节都是负数
5.2 字符流中编码解码问题
- 字符流抽象基类
- Reader:字符输入流的抽象类
- Writer:字符输出流的抽象类
- 字符流中和编码解码问题相关的两个类:
InputStreamReader
OutputStreamWriter
package test;
/*InputStreamReader:是从字节流到字符流的桥梁
它读取字节,并使用指定的编码将其解码为字符
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
OutputStreamhriter:是从字符流到字节流的桥梁
是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集*/
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"),"GBK");
osw.write("中国");
osw.close();
//1, InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\fos.txt"));
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\fos.txt"),"GBK");
int ch;
while((ch= isr.read()) !=-1) {
System.out.print((char)ch); //1:�й�;2:中国,因为第二次和编码格式GBK一样
}
isr.close();
}
}
5.3 字符输出流
方法名 | 说明 |
---|---|
void write(int c) | 写一个字符 |
void write(char[ ] cbuf) | 写一个字符数组 |
void write(char[ ] cbuf,int off,int len) | 写一个字符数组的一部分 |
void write(String str) | 写一个字符串 |
void write(String str,int off,int len) | 写一个字符串的一部分 |
方法名 | 说明 |
---|---|
flush() | 刷新流还可以写数据 |
close() | 关闭流,释放资源,但在关闭之前先刷新。关闭后不能写数据 |
- 范例
package test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\fos.txt"));
//1,void write(int c) 写一个字符
/*osw.write(97);
osw.write(98);
//ab
//void flush():刷新流
osw.flush();*/
//2,void write(char[ ] cbuf) 写一个字符数组
/*char[] chs = {'a','b','c'};
// osw.write(chs);
//abc
//3,void write(char[ ] cbuf,int off,int len) 写一个字符数组的一部分
osw.write(chs,1, 2); //bc,1索引开始,写两个*/
//4,void write(String str) 写一个字符串
// osw.write("abcef"); //abcef
//5,void write(String str,int off,int len) 写一个字符串的一部分
osw.write("abcdef",0, "abcdef".length()); //abcdef
osw.close();
}
}
5.4 字符输入流
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据 |
int read(char([ ] cbuf) | 一次读一个字符数组数据 |
- 范例
package test;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\fos.txt"));
//1,int read() 一次读一个字符数据
/*int ch;
while((ch= isr.read()) != -1) {
System.out.print((char)ch);
// Java
// Python
// Scala
}*/
//2,int read(char([ ] cbuf) 一次读一个字符数组数据
char[] chs = new char[1024];
int len;
while((len= isr.read(chs)) != -1) {
System.out.print(new String(chs,0,len));
// Java
// Python
// Scala
}
isr.close();
}
}
- 案例:Copy文件
package test;
import java.io.*;
public class CopyJavaDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("E:\\test\\Demo.java");
FileWriter fw = new FileWriter("E:\\test\\Demo\\Demo.java");
//读写数据,一次一个
/*int ch;
while((ch=fr.read()) != -1) {
fw.write(ch);
}*/
char[] chs = new char[1024];
int len;
while((len=fr.read(chs)) != -1) {
fw.write(chs,0,len);
}
fw.close();
fr.close();
}
}
5.5 字符缓冲流
BufferedReader
:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。默认值足够大,可用于大多数用途BufferedWriter
:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途- 构造方法
- BufferedReader(Reader in)
- BufferedWriter(Writer out)
package test;
import java.io.*;
public class BufferedStreamDemo {
public static void main(String[] args) throws IOException {
//2,BufferedWriter(Writer out)
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\fos.txt"));
bw.write("java\r\n");
bw.write("python\r\n");
bw.close();
//java
// python
//1,BufferedReader(Reader in)
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\fos.txt"));
//一次读一个字符数据
/*int ch;
while((ch=br.read()) != -1) {
System.out.print((char)ch);
// java
// python
}
br.close();*/
//一次读一个字符数组
char[] chs = new char[1024];
int len;
while((len=br.read(chs)) != -1) {
System.out.println(new String(chs,0,len));
// java
// python
}
br.close();
}
}
5.6 字符缓冲流特有功能
BufferedReader
public String readLine()
:读一行文字。结果包含行的内容的字符串,不包括任何行终止字符,如果流的结尾已经到达,则为null
BufferedWriter
void newLine()
:写一行行分隔符, 行分隔符字符串由系统属性定义
package test;
import java.io.*;
public class BufferedStreamDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲流输出流
/*BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\fos.txt"));
for(int i=0;i<5;i++) {
bw.write("hello"+i);
// bw.write("\r\n");
//2,void newLine():写一行行分隔符, 行分隔符字符串由系统属性定义
bw.newLine();
bw.flush();
}
bw.close();*/
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\fos.txt"));
//2,public String readLine():读一行文字
String line;
while((line=br.readLine()) != null) {
System.out.println(line);
/*
hello0
hello1
hello2
hello3
hello4*/
}
br.close();
}
}
5.7 字符缓冲流Copy文件(推荐使用)
package test;
import java.io.*;
public class BufferedStreamDemo {
public static void main(String[] args) throws IOException {
//根据数据源创建字符缓冲流输入对象
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\fos.txt"));
//根据数据源创建字符缓冲流输出对象
BufferedWriter bw = new BufferedWriter(new FileWriter(("E:\\test\\Demo\\copy.txt")));
String line;
while((line=br.readLine()) !=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
5.8 IO流小结
-
字节流小结
-
字符流小结
5.9 案例大全
- 案例1:集合到文件
package test;
import java.io.*;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) throws IOException {
ArrayList<String> array = new ArrayList<>();
array.add("java");
array.add("python");
array.add("scala");
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));
for(String s:array) {
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
}
}
- 案例2:文件到集合
package test;
import java.io.*;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\java.txt"));
ArrayList<String> array = new ArrayList<>();
String line;
while((line=br.readLine()) !=null) {
array.add(line);
}
br.close();
for(String s:array) {
System.out.println(s);
/*java
python
scala*/
}
}
}
- 案例3:点名器
package test;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;
public class Demo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\java.txt"));
ArrayList<String> array = new ArrayList<>();
String line;
while((line=br.readLine()) !=null) {
array.add(line);
}
br.close();
Random r = new Random();
int index = r.nextInt(array.size());
String name = array.get(index);
System.out.println(name); //第一次:Java;第二次:Python;第三次:Python;第四次:Scala
}
}
- 案例4:集合到文件(改进版)
package test;
import java.io.*;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) throws IOException {
ArrayList<Student> array = new ArrayList<>();
Student s1 = new Student("小明",10);
Student s2 = new Student("小白",20);
Student s3 = new Student("小黑",30);
array.add(s1);
array.add(s2);
array.add(s3);
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));
for(Student s:array) {
StringBuilder sb = new StringBuilder();
sb.append(s.getName()).append(",").append(s.getAge());
bw.write(sb.toString()); //需要的是一个字符串
bw.newLine();
bw.flush();
}
bw.close();
/*小明,10
小白,20
小黑,30*/
}
}
- 案例5:文件到集合(改进版)
package test;
import java.io.*;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\java.txt"));
ArrayList<Student> array = new ArrayList<>();
String line;
while((line=br.readLine()) != null) {
String[] strArray = line.split(","); //获取line数据按照逗号进行分割,存入字符串数组
Student s = new Student();
s.setName(strArray[0]);
s.setAge(Integer.parseInt(strArray[1])); //需要的是int类型的数据
array.add(s);
}
br.close();
for(Student s:array) {
System.out.println(s.getName()+","+s.getAge()); //字符串转为int
/*小明,10
小白,20
小黑,30*/
}
}
}