Java基础知识 25
字符流
字符流的由来:因为一个中文汉字占2个字节,如果使用字节流操作,就需要对这个汉字进行拆分和合并,但是比较麻烦,因此Java为更加方便的操作中文给我们提供了一个字符流,我们知道,数据在计算机上的最小单位是字节,计算机上操作数据还是要对最小单位进行操作,于是这个字符流底层还是要使用字节流,那么要使用字符流,就要对这个中文汉字进行差分和合并,我们按照码表进行拆分。
字符流=字节流+码表
编码:按照某种编码方式,把字符串转换成字节数组。
解码:按照某种编码方式,把字节数组转换成字符串。
也就是说,当我们在编码和解码的时候,使用的是同一张码表,就不会出现乱码的现象。
//编码
String str = "爱生活";
//按照平台默认码表进行编码
byte[] bytes = str.getBytes();
System.cout.println(Arrays.toString(bytes));
//解码
String s = new String(bytes);
System.out.println(s);
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Mytest {
public static void main(String[] args) throws UnsupportedEncodingException {
//编码:按照某种编码格式,把字符串转换成字节数组,把看得懂的,转换成看不懂的。
//解码:把字节数组转成按照某种编码方式转换成字符串,把看不懂的,转换成看得懂的。
String str="爱生活";
//编码:按照平台默认的方式编码
byte[] bytes = str.getBytes();
System.out.println(Arrays.toString(bytes));
//解码:
String str1 = new String(bytes);
System.out.println(str1);
//也就是说,我们在编码和解码的时候使用的是同一张码表,就不会出现乱码的问题。
String str2="数据结构与算法";
//编码
byte[] bytes1 = str2.getBytes("UTF-8");
System.out.println(Arrays.toString(bytes1));
//解码
String str3 = new String(bytes1,"GBK");
System.out.println(str3);
//出现乱码的原因:就是编解码使用的不是同一张码表。
}
}
OutputStreamWrite类
OutputStreamWrite类是字符流通向字节流的桥梁,可以使用指定的码表将要写入流的字符编码成字节,它使用的子符集可以由名称指定或者显示给定,否则将接受平台默认的字符集。
OutputStreamWrite(OutputStream out)
创建使用默认字符编码的OutputStreamWrite。
OutputStreamWrite(OutputStream out,String charsetName)
创建使用指定子符集的OutputStreamWrite。
OutputStreamWrite(OutputStream out):
因为字节输出流是抽象类,是所有字节输出流的父类,我们想要封装字节输出流,必须封装它的一个子类对象。
OutputStreamWrite out = new OutputStreamWrite(new FileOutputStream(“a.txt”));
输出流所关联的文件,如果不存在,会自动创建
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("a.txt"));
可以指定码表
OutputStreamWriter out2 = new OutputStreamWriter(new FileOutputStream("a.txt"), "GBK");
往文件中写入数据:
out.flush();字符流,要刷新,把缓冲区的数据刷新到磁盘中。
out.close();刷新并关闭。
out.write(new char[]{‘大’,‘唐’,‘不’,‘夜’,‘城’},2,3);一次写入字符串中的一部分,2表示初始索引,3表示字符串长度。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Mytest3 {
public static void main(String[] args) throws IOException {
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("b.txt"));
out.write("陕西省西安市雁塔区");
//字符流,要刷新,把缓冲区中的数据,刷新到磁盘符中。
out.flush();
out.write("\r\n");
//一次写入一个字符数组
out.write(new char[]{'大','唐','芙','蓉','园'});
out.write("\r\n");
//字符流,要刷新,把缓冲区中的数据,刷新到磁盘符中。
out.flush();
//一次写入一个数组的一部分,从2索引处开始,长度为3。
out.write(new char[]{'大','唐','不','夜','城'},2,3);
out.write("\r\n");
//字符流,要刷新,把缓冲区中的数据,刷新到磁盘符中。
out.flush();
//释放资源
out.close();
}
}
追加写入:在你传入的字节流中,给个true,表示追加写入。
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(“b.txt”,true));
使用try…catch…语句对异常进行捕获处理。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Mytest2 {
public static void main(String[] args) {
//使用try...catch...语句对流的异常进行处理
OutputStreamWriter out=null;
try {
//追加写入 在你传入的字节流中,给个true,表示追加写入
out = new OutputStreamWriter(new FileOutputStream("c.txt", true));
out.write("陕西省西安市");
out.write("\r\n");
out.flush();
//一次写入一个字符数组
out.write(new char[]{'大','唐','芙','蓉','园'});
out.write("\r\n");
out.flush();
//一次写入一个字符数组的一部分
out.write(new char[]{'大','唐','芙','蓉','园'},2,2);
out.write("\r\n");
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
InputStreamReader类
InputStreamReader是字节流通向字符流的桥梁,它使用指定的码表读取字节并将解码为字符,它使用的字符集可以由名称指定或者显示给定,或者可以接受平台默认的子符集。
InputStreamReader(InputStream in)
创建一个使用默认子符集的InputStreamReader。
InputStreamReader(InputStream in,String charsetName)
创建使用指定子符集的InputStreamReader。
//输入流所关联的文件不存在,就会报错。
InputStreamReader in = new InputStreamReader(new FileInputStream("d.txt"));
//也可以指定码表
InputStreamReader gbk = new InputStreamReader(new FileInputStream("d.txt"), "GBK");
读取文件中的数据
ch = in.read();
System.out.println(ch);
如果读取不到,就返回-1,我们可以使用-1来进行判断文件是否读取完毕
public class Mytest2 {
public static void main(String[] args) throws IOException {
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("e.txt"));
out.write("陕西省西安市");
out.flush();
InputStreamReader in = new InputStreamReader(new FileInputStream("e.txt"));
//一次读取一个字符
int ch = in.read();
System.out.println(ch);
ch = in.read();
System.out.println(ch);
ch = in.read();
System.out.println(ch);
ch = in.read();
System.out.println(ch);
ch = in.read();
System.out.println(ch);
ch = in.read();
System.out.println(ch);
//如果读取不到,就返回-1,我们可以使用-1来进行判断文件是否读取完毕
ch = in.read();
System.out.println(ch);
//程序最后别忘了释放资源。
in.close();
out.close();
}
}
可以使用一个字符数组充当容器,可以提高效率,把字符串一次读取到这个容器中
char[] chars = new char[1024];
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Mytest3 {
public static void main(String[] args) throws IOException {
InputStreamReader in = new InputStreamReader(new FileInputStream("e.txt"));
//定义一个字符数组来充当容器,可以一次读取到这个容器中
char[] chars = new char[1024];
//一次读取1024个字符,放到字符数组中,返回的实际上取到的字符个数。
int len = in.read(chars);
System.out.println(len);
System.out.println(Arrays.toString(chars));
//把字符数组转换成字符串
String s = String.valueOf(chars);
System.out.println(s);
//把字符数组转换成字符串
String s1 = new String(chars);
System.out.println(s1);
in.close();
}
}
int len = in.read(chars, 0, 3);
我们可以一次读取一部分字符,放到字符数组中,从0索引处开始把字符放进去,3为读取字符的长度
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Mytest4 {
public static void main(String[] args) throws IOException {
InputStreamReader in = new InputStreamReader(new FileInputStream("e.txt"));
//定义一个字符数组来充当容器,可以一次读取到这个容器中
char[] chars = new char[1000];
//我们可以一次读取一部分字符,放到字符数组中,从0索引处开始把字符放进去,3为读取字符的长度
int len = in.read(chars, 0, 3);
System.out.println(len);
System.out.println(Arrays.toString(chars));
in.close();
}
}
使用try…catch…语句对流的异常进行捕获处理
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Mytest5 {
public static void main(String[] args) {
//使用try......catch......语句进行流的异常处理
InputStreamReader in=null;
try {
in = new InputStreamReader(new FileInputStream("e.txt"));
//定义一个字节数组
char[] chars = new char[1000];
//开始读取字符,读取字符串中的一部分字符,放到字符数组中。
int len = in.read(chars, 0, 6);
System.out.println(len);
System.out.println(Arrays.toString(chars));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用字符流来复制文本
使用字符流来读取文本
InputStreamReader reader = new InputStreamReader(new FileInputStream(“Mytest.java”));
使用字符流来写入文本
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream (“C:\Users\YangJian\Desktop\aaa.java”));
import java.io.*;
public class Mytest {
public static void main(String[] args) throws IOException {
//使用字符流来复制文本
//使用字符流来读取文本
InputStreamReader reader = new InputStreamReader(new FileInputStream("Mytest.java"));
//使用字符流来写入文本
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\YangJian\\Desktop\\aaa.java"));
int len=0;
while ((len=reader.read())!=-1){
writer.write(len);
writer.flush();
}
//最后释放资源
reader.close();
writer.close();
}
}
流的异常处理:使用try…catch…语句,使用字符流来复制文本文件
import java.io.*;
public class Mytest3 {
public static void main(String[] args) {
InputStreamReader reader =null;
OutputStreamWriter writer =null;
try {
//使用字符流来复制文本文件
reader = new InputStreamReader(new FileInputStream("c.txt"));
writer = new OutputStreamWriter(new FileOutputStream("C:\\Users\\YangJian\\Desktop\\aaa.java",true));
//使用一个字符数组来进行复制
char[] chars = new char[1000];
int len=0;
int count=1;
while ((len=reader.read())!=-1){
System.out.println("循环次数"+(count++));
writer.write(chars);
writer.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
便捷字符流
   父类-------------------------------->子类
InputStreamReader------------------------->FileReader
OutputStreamWriter------------------------>FileWriter
便捷字符流,唯一就是不能指定编码,它也没有自己特有的方法,用的都是继承下来的方法。
FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新FileReader。
FileWriter(File file)
在给定从中读取数据的File的情况下创建一个新FileReader。
FileReader reader = new FileReader(new File("c.txt"));
FileReader reader1 = new FileReader("e.txt");
FileWriter(File file)
根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(String fileName)
根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append)
根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。
import java.io.*;
public class Mytest {
public static void main(String[] args) throws IOException {
FileWriter writer = new FileWriter("copy.java");
char[] chars = new char[1000];
int len=0;
int count=1;
while ((len=reader1.read(chars))!=-1){
System.out.println("循环次数"+(count++));
writer.write(chars,0,len);
writer.flush();
}
reader1.close();
writer.close();
}
}
高效字符流
BufferedReader----------------------BufferedWriter
BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader reader = new BufferedReader(new FileReader(“Mytest.java”));
BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter writer= new BufferedWriter(new FileWriter(“123.java”));
import java.io.*;
public class Mytest {
public static void main(String[] args) throws IOException {
//高效的字符流
//BufferedReader
//BufferedWriter
/*构造方法摘要
BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。*/
BufferedReader reader = new BufferedReader(new FileReader("Mytest.java"));
/* BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。*/
BufferedWriter writer= new BufferedWriter(new FileWriter("123.java"));
char[] chars = new char[1024];
int len=0;
while ((len=reader.read())!=-1){
writer.write(chars,0,len);
writer.flush();
}
reader.close();
writer.close();
}
}
高效的字符流
BufferedReader 里面有特有的方法 String readLine() 一次读一行文本
BufferedWriter void newLine() 写入一个换行符,具有平台兼容性。
使用高效的字符流。读取一行,写入一行来复制文件,逐行复制。
import java.io.*;
public class Mytest2 {
public static void main(String[] args) throws IOException {
//高效的字符流
//BufferedReader 里面有特有的方法 String readLine() 一次读一行文本
//BufferedWriter void newLine() 写入一个换行符,具有平台兼容性。
//使用高效的字符流。读取一行,写入一行来复制文件,逐行复制。
BufferedReader reader = new BufferedReader(new FileReader("MyTest.java"));
BufferedWriter writer = new BufferedWriter(new FileWriter("456.java"));
//循环的进行读取一行,写入一行
//一行一行的读取,读取不到的返回null
String line=null;
while ((line=reader.readLine())!=null){
writer.write(line);
writer.newLine();//换行符,相当于Writer.write("\r\n")
writer.flush();
}
reader.close();
writer.close();
}
}