IO流(二. 字符流)
字符流
字符流的底层实际上就是字节流+编码方式
- 在读写文件需要对文本内容进行处理:按行处理、比较特定字符的时候一般会选择字符流
- 仅仅读写文件,不处理内容,一般选择字节流
1.1常见字符集(码表)

-
ASCII编码: ASCII字符集(码表)的编码方式,1个字节,最多能表示256个字符,适用于英文
-
GBK编码:GBK字符集(码表)的编码式,用1个字节表示英文,用2个字节表示中文
-
UTF-8编码:Unicode字符集(码表)的编码方式,用1个字节表示英文,用3个字节表示中文
windows平台默认编码方式是GBK,而ideal和工作中用的编码方式是UTF-8
1.2 编解码方法
编码方法
方法 | 说明 |
---|---|
public byte[] getBytes() | 使用平台的默认字符集将该String 编码为一系列字节,将结果存储到新的字节数组中 |
public byte[] getBytes(String charsetName) | 使用命名的字符集将这个String 编码成一个字节序列,将结果存储到一个新的字节数组中 |
解码方法
方法 | 说明 |
---|---|
String(byte[] bytes) |
通过使用平台的默认字符集解码指定的字节数组来构造新的 String |
String(byte[] bytes, String charsetName) |
构造一个新的String 由指定用指定的字节的数组解码 |
示例代码
public class Encoding {
public static void main(String[] args) throws UnsupportedEncodingException {
String arr="中国";
//使用默认的UTF-8编码
byte[] bytes = arr.getBytes();
//System.out.println(Arrays.toString(bytes));
//使用指定的的GBK编码
//byte[] byte2 = arr.getBytes("GBK");
//System.out.println(Arrays.toString(byte2));
//默认使用UTF-8解码
String s = new String(bytes);
System.out.println(s);
//GBK解码
//String s2 = new String(byte2,"GBK");
//System.out.println(s2);
}
}
2.字符输入流
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("day11\\a.txt");
int len;
char[] c = new char[10];
while ((len= fr.read(c))!=-1){
//该String构造方法,可以将传进去的字符类型数组,转换成String输出,并可指定输出部分内容
System.out.println(c);
System.out.println(new String(c,0,5));
}
//关流
fr.close();
}
}
3.字符输出流
public class FileWriteDemo {
public static void main(String[] args) throws IOException {
/**
* 如果文件不存在,则会自动创建
* 如果存在,则会清空其内容,需需要续写则需要打开构造函数的续写开关
*/
FileWriter fw = new FileWriter("day11\\a.txt",false);
fw.write("中国");
fw.write("\r\n");
fw.write("97");
fw.write("\r\n");
//写入部分String内容,从下标为2的字符开始,往后写入2个,实际写入文件的是 好声
fw.write("中国好声音",2,2);
fw.write("\r\n");
//写入部分数组内容,从下标为3的字符开始,往后写入2个,实际写入文件的是 45
fw.write(new char[]{'1','2','3','4','5'},3,2);
fw.write("\r\n");
/*
* 字节流会直接与硬盘进行数据交互,所以即便不做close,数据也会被写入文件中
字符流则会先把数据存入缓冲区当中,再通过flush() 或close() 刷新到本地文件中,如果没有做,文件中就不会有数据
拓展:在不调用flush() 或close()的情况下,一旦缓冲区超过8192个字节,就会被强制刷新出来
*/
/*for (int i = 1; i <= 8193; i++) {
fw.write("q");
}*/
//fw.flush();
fw.close();
}
}
为什么有时候我们看到文件会乱码?
原因就是编解码方式不一样。另外,字节流读取中文出现乱码的原因是:idea中默认的编码方式是UTF-8,中文占据三个字节,但是字节流读取中文时,一次读一个字节,就会造成乱码。
想要解决乱码问题,就需要用到转换流,将字节流转换成字符流,不存在字符流转字节流,没有必要。
方法名 | 说明 |
---|---|
InputStreamReader(InputStream in) | 使用默认字符编码创建InputStreamReader对象 |
InputStreamReader(InputStream in,String chatset) | 使用指定的字符编码创建InputStreamReader对象 |
OutputStreamWriter(OutputStream out) | 使用默认字符编码创建OutputStreamWriter对象 |
OutputStreamWriter(OutputStream out,String charset) | 使用指定的字符编码创建OutputStreamWriter对象 |
jdk11版本之前,使用以上的转换流
//将字节输入流转换成字符输入流
//如果文件是GBK类型,就在InputStreamReader构造参数里面写上解码方式
InputStreamReader isr = new InputStreamReader(new FileInputStream("day11\\c.txt"),"gbk");
int a;
while ((a= isr.read())!=-1){
System.out.println((char) a);
}
isr.close();
jdk11以后,新增了字符流的的构造方法
//如果文件是GBK,就在FileReader构造参数里面调用Charset.forName("GBK")写上解码方式
FileReader fr = new FileReader("day11\\c.txt", Charset.forName("gbk"));
int a;
while ((a= fr.read())!=-1){
System.out.println((char) a);
}
fr.close();
4.字符缓冲流
和字节流一样,字符流同样也有缓冲流,并且还有自己特有的方法
字符缓冲输入流
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader("day11\\a.txt"));
/**
* 特有的readLine()方法,使用字符缓冲输入流一次读取一整行的数据
*/
/*String s = "";
while((s= br.readLine())!=null){
System.out.println(s);
}*/
int len;
char[] chars = new char[2];
while ((len=br.read(chars))!=-1){
System.out.println(new String(chars,0,len));
}
br.close();
}
}
字符缓冲输出流
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\a.txt"));
bw.write("admin");
//bw.write("\r\n");
//特有的换行方法:newLine(),防止系统换行符冲突,可以跨平台(win,mac,linux)使用
bw.newLine();
bw.write("12345");
bw.close();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现