Java IO流之字符流(OutputStreamWriter、InputStreamReader、BufferedWriter、BufferedReader)
一、字符流出现的原因
由于字节流操作中文不是特别方便,所以,java就提供了字符流
字符流 = 字节流 + 编码表
二、String类中的编码和解码问题
编码: 就是把字符串转换成字节数组
-
把一个字符串转换成一个字节数组的方法
- public byte[] getBytes();使用平台的默认字符集将此 String编码为 byte 序列,并将结果存储到一个新的 byte 数组中
- public byte[] getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
解码: 把字节数组转换成字符串
-
把一个字符数组转换成一个字符串的方法
- public String(byte[] bytes): 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
- public String(byte[] bytes, String charsetName) 通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String
-
编码:把看得懂的变成看不懂的: String – byte[]
-
解码:把看不懂的变成看得懂的: byte[] – String
import java.io.UnsupportedEncodingException; import java.util.Arrays; public class Test2 { public static void main(String[] args) throws UnsupportedEncodingException { String s = "你好"; //使用IDEA默认的utf-8编码,一个汉字占三个字节 byte[] bytes = s.getBytes(); System.out.println(Arrays.toString(bytes)); //指定为GBK编码,一个汉字占两个字节 byte[] bytes1 = s.getBytes("GBK"); System.out.println(Arrays.toString(bytes1)); //使用默认utf-8编码表来解码保存了utf-8的字节数组 String s1 = new String(bytes); System.out.println(s1); //使用GBK编码表解码保存了GBK的字符数组 String s2 = new String(bytes1, "GBK"); System.out.println(s2); //用utf-8解码保存了GBK编码编码表编码的字符串,会出现乱码 String s3 = new String(bytes1, "UTF-8"); System.out.println(s3); } } //输出: [-28, -67, -96, -27, -91, -67] [-60, -29, -70, -61] 你好 你好 ���
三、OutputStreamWriter
-
构造方法
- OutputStreamWriter(OutputStream out):根据默认编码(GBK)把字节流的数据转换为字符流
- OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
-
写入数据
- public void write(int c) 写一个字符
- public void write(char[] cbuf) 写一个字符数组
- public void write(char[] cbuf,int off,int len) 写一个字符数组的 一部分
- public void write(String str) 写一个字符串
- public void write(String str,int off,int len) 写一个字符串的一部分
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class Test3 { public static void main(String[] args) throws IOException { OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("e:\\test.txt")); out.write(97); out.write("你好"); char[] chars = {'你', '好'}; out.write(chars); out.flush(); out.close(); } } //输出:a你好你好
四、InputStreamReader
-
构造方法
- InputStreamReader(InputStream is):用默认的编码(GBK)读取数据
- InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
-
读入数据
- public int read() 一次读取一个字符,如果已到达流的末尾,则返回 -1
- public int read(char[] cbuf) 一次读取一个字符数组 如果没有读到 返回-1
import java.io.*; public class Test4 { public static void main(String[] args) throws IOException { //e:\\test.txt下保存的为"a你好" InputStreamReader in = new InputStreamReader(new FileInputStream("e:\\test.txt")); //定义一个容器 char[] chars = new char[100]; int len = in.read(chars, 0, 17);//从0开始读,读取17个字符放到容器中 System.out.println(len); System.out.println("------------------"); System.out.println(new String(chars, 0, len)); System.out.println(String.valueOf(chars, 0, len)); in.close(); } } //输出: 4 ------------------ a你好 a你好
-
使用字符流复制文本文件
import java.io.*; public class Test5 { public static void main(String[] args) throws IOException { InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("e:\\test.txt")); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("e:\\test1.txt")); int len = 0; char[] chars = new char[1024]; while ((len=inputStreamReader.read(chars))!=-1){ outputStreamWriter.write(chars,0,len); outputStreamWriter.flush(); } outputStreamWriter.close(); inputStreamReader.close(); } }
五、字符缓冲流(BufferedWriter、BufferedReader)
- 高效的字符输出流: BufferedWriter
构造方法: public BufferedWriter(Writer w) - 高效的字符输入流: BufferedReader
构造方法: public BufferedReader(Reader e) - 字符缓冲流的特殊功能
- BufferedWriter: public void newLine():根据系统来决定换行符 具有系统兼容性的换行符
- BufferedReader: public String readLine():一次读取一行数据 是以换行符为标记的,读到换行符就换行 没读到数据返回null
六、把文本文件中的数据存储到集合中
import java.io.*;
import java.util.ArrayList;
public class Test6 {
public static void main(String[] args) throws IOException {
// 把文本文件中的数据存储到集合中
BufferedReader bufferedReader = new BufferedReader(new FileReader("file.txt"));
int len = 0;
char[] chars = new char[1024 * 8];
ArrayList<String> list = new ArrayList<>();
while (true){
String s = bufferedReader.readLine();
if(s!=null){
list.add(s);
}else {
break;
}
}
System.out.println(list);
bufferedReader.close();
}
}
七、把集合中的数据存储到文本文件
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class Test7 {
public static void main(String[] args) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"));
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
for (String s : list) {
bufferedWriter.write(s);
bufferedWriter.newLine();//写入一个换行符
}
bufferedWriter.close();
}
}