本质:字符流 = 字节流 + 编码
意义:字符流是为了适应除英文字母以外的国家所诞生的概念.
比如为了储存一个文本文件,那么可以直接将中文(即字符流)转换为字节(即字节流).这直接省去了要把中文转换成Byte再去转换成字节的麻烦了.
注意:字符流只能输出输入文本文件,不能输入输出多媒体文件.
因为多媒体文件的内容是不存在码表的,如果用字符流读写多媒体文件的话,字符流会将其内容强制对应到码表上,这样就会导致多媒体的文件数据出错.
普通字节流的文本逻辑: 文本/多媒体数据 <-----> Byte <-----> 字节集
字符流的文本逻辑: 文本 <-----> (隐性:字符变成编码) <------> 字节集;
默认编码格式:
OutputStreamWriter 自定义对象名 = new OutputStreamWriter(new FileOutputStream(路径/Flie对象));
列如:
OutputStreamWriter outputStreamWriterObj = new OutputStreamWriter(new FileOutputStream("\outputStreamWriterObj.txt"));
指定编码格式:
OutputStreamWriter 自定义对象名 = new OutputStreamWriter(new FileOutputStream(路径/File对象),用来表示编码的字符串);
列如:
OutputStreamWriter outputStreamWriterObjTwo = new OutputStreamWriter(new FileOutputStream("\outputStreamWriterObj.txt",true),“GB18030”);
默认编码格式:
InputStreamReader 自定义对象名 = new InputStreamReader(new FileInputStream(路径/File对象));
列如:
InputStreamReader inputStreamReaderObj = new InputStreamReader(new FileInputStream(“C:\Users\1\Documents\Tencent Files\aaa.txt”));
指定编码格式:
InputStreamReader 自定义对象名 = new InputStreamReader(new FileInputStream(路径/File对象),用来表示编码的字符串);
列如:
InputStreamReader inputStreamReaderObjAA = new InputStreamReader(new FileInputStream(“C:\Users\1\Documents\Tencent Files\aaa.txt”),“GBK”);
注意:输入字符流在处理文本时,需要考虑到原先文本的编码.不管是默认编码格式还是指定编码格式,都必须同被读文本的文件编码
InputStreamReader 把读过来的字节转换为字符
OutputStreamWriter 把字符转为字节去写入
字符输出流对象名.close()
意义:释放资源,在释放资源的同时会自动触发刷新机制
方法2/
字符输出流对象名.flush()
意义:刷新
方法3/
字符输出流对象名. getEncoding()
返回此流使用的字符编码的名称。
方法4/
字符输出流对象名.write(char型数组,起始位置索引值,截取长度)
列如:
//写入指定范围的字符数组.
char[] charParam = {96, 97, 98, 99, 'Q', 'W', 'E'};
outputStreamWriterObj.write(charParam, 3, 3);// 99 Q W
outputStreamWriterObj.flush();//刷新
意义:截取字符数组的一部分数据来写入。
方法5/
字符输出流对象名.write(char型数组);
列如:
//字符(char)数组方式写入
char[] charParam = {96, 97, 98, 99, 'Q', 'W', 'E'};
outputStreamWriterObj.write(charParam);
outputStreamWriterObj.flush();//刷新
意义:将整个数组数据写入
方法6/
字符输出流对象名.write(int c)
写入一个一个字符
方法7/
字符输出流对象名.write(String字符串, 起始位置索引值, 截取长度)
列如:
outputStreamWriterObj.write("中国第一", 1, 2);//国第
outputStreamWriterObj.flush();//刷新
意义:将字符串的一部分当作数据写入
方法8/
字符输出流对象名.write(String字符串)
列如:
//直接写入字符串
outputStreamWriterObj.write("中国第一");
outputStreamWriterObj.flush();//刷新
意义:将整个字符串当作数据写入
输入流的方法:
方法1/
字符输入流对象名.close()
意义:关闭流并释放与之相关联的任何系统资源。
方法2/
字符输入流对象名.getEncoding()
返回此流使用的字符编码的名称。
方法3/
字符输入流对象名.read()
读一个字符
方法4/
字符输入流对象名.read(char型数组, 起始位置索引值, 截取长度)
将字符读入数组的一部分。
方法5/
字符输入流对象名.read(char型数组)
列如:
char[] charParamTwo = new char[1024];
int len;
while((len = inputStreamReaderSuper.read(charParamTwo))!=-1){ // 此处len表示的时,长度为1024的数组'chaparamTwo'中有多少个数组填满了元素,如为500个,则read方法返回500个.
outputStreamWriterSuper.write(charParamTwo, 0, len); //len 和 length的区别,如果直接使用获取长度的length,则内容无区别,但是文件大小会大一点.
//如果为len,同样内容无区别,但文件大小会小一点.
}
意义:读入整个字节数组的数据.
UTF-8编码中,一个汉字需要三个负数字节组成
GBK编码中,一个汉字需要二个负数字节组成
在字符中流,可以指定数据编码.
不指定的话,则根据系统版本而选择编码.
解码时必须根据其对应的编码进行解码,类似易语言中 编码用UTF-8 那么解码就必须用UTF-8
1/用系统默认编码:
字符/字符串.getBytes()
; //用系统默认编码进行编码
列如:
byte[] bytes = “世界”.getBytes();
2/用指定编码:
字符/字符串.getBytes(编码)
; //用指定编码去编码
列如:
byte[] bytesTwo = “世界”.getBytes(“GBK”);
1/用系统默认编码:
new String(需要被编码的String类型内容);
列如:
String bytesBack = new String(bytes);
2/用指定编码:
new String(需要被编码的String类型内容,编码);
列如:
String bytesTwoBack = new String(bytesTwo,“GBK”);
FileWriter 和 FileReader 分别是 OutputStreamWriter 和 InputStreamReader的升级版
原因在于原先的字符IO创建语句过于麻烦,所以升级版的目的在于简化代码.功能无区别.
格式:
FileWriter 自定义对象名 = new FileWriter(路径/File对象);
列如:
FileWriter fileWriterObj = new FileWriter("\outputStreamWriterSuper.txt");
格式:
FileReader 自定义对象名 = new FileReader(路径/File对象);
列如:
FileReader fileReaderObj = new FileReader("\outputStreamWriterObj.txt");
如同字节流的缓冲流一样,字符流的缓冲流同样可以提高数据的读写效率.
1/字符输出缓冲流
格式:
BufferedWriter 自定义对象名 = new BufferedWriter(new FileWriter(路径/File对象));
列如:
BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\bufferedWriterObj.txt"));
2/字符输入缓冲流
格式:
BufferedReader 自定义对象名 = new BufferedReader(new FileReader(路径/File对象));
列如:
BufferedReader bufferedReaderObj = new BufferedReader(new FileReader(“C:\Users\1\Documents\Tencent Files\aaa.txt”))
多数方法同同字符流升级版和基本版一样,而重点掌握的特有方法有3个:
1/
格式:自定义输入流对象名.readLine()
列如:bufferedReaderObj.readLine()
意义:一次只读取一行字符串
2/
格式:自定义输出流对象名.ritervoid newLine()
列如:bufferedWriterObj.newLine();
意义:自动根据内容被读文件内容来写入换行符.
用于文本中的换行符.它的作用是先判断获取到的该行字符串有没有换行符,
如果有,不论你是什么系统(系统不同,换行符也不同),都能将文本中的的隐性换行符给替代掉,用newLine表示换行.
如果不用,写出的文件很可能缺失了原有的换行符.
3/
格式:自定义输出流对象名. write(字符串/char数组);
列如:bufferedWriterObj.write(temp);
意义:一次写一个字符串
public class Characeter {
public static void main(String[] args) throws Exception {
// 一/字符串的编码与解码
//默认编码和默认解码
byte[] bytes = "世界".getBytes();//编码 --- 系统默认编码进行编码.
System.out.println("默认编码:" + Arrays.toString(bytes));
String bytesBack = new String(bytes);//解码 --- 系统默认编码进行解码.
System.out.println("默认解码" + bytesBack);
System.out.println("===========");
//指定编码和指定解码
byte[] bytesTwo = "世界".getBytes("GBK");//编码 --- 用指定编码GBK进行编码,如若要对其进行解码,其解码的编码也要一致,比如也要是GBK.
System.out.println("指定编码GBK:" + Arrays.toString(bytesTwo));
String bytesTwoBack = new String(bytesTwo, "GBK");//解码 --- 用指定编码进行解码,被解码之内容所用的编码,要同此一致,如两者都是GBK编码.
System.out.println("指定解码GBK:" + bytesTwoBack);
System.out.println("===========");
// 二/字符流
//创建输出字节流
OutputStreamWriter outputStreamWriterObj = new OutputStreamWriter(new FileOutputStream("\\outputStreamWriterObj.txt", true));
OutputStreamWriter outputStreamWriterObjTwo = new OutputStreamWriter(new FileOutputStream("\\outputStreamWriterObj.txt", true), "GB18030");
//字符流(OutputStreamWriter)写数据的五种方式
//第一种,以int型写,系统会自动转换成一个一个的char型.
outputStreamWriterObj.write(121212);
outputStreamWriterObj.flush();//在写入字节流后,需要用flush方法进行刷新.如果不刷新的话,用给write方法传递的数据就无法成功写入到文件中.
//第二种,字符(char)数组方式写入
char[] charParam = {96, 97, 98, 99, 'Q', 'W', 'E'};
outputStreamWriterObj.write(charParam);
outputStreamWriterObj.flush();//刷新
//第三种,写入指定范围的字符数组.
outputStreamWriterObj.write(charParam, 3, 3);// 99 Q W
outputStreamWriterObj.flush();//刷新
//第四种,直接写入字符串
outputStreamWriterObj.write("中国第一");
outputStreamWriterObj.flush();//刷新
//第四种,写入字符串的一部分
outputStreamWriterObj.write("中国第一", 1, 2);//国第
outputStreamWriterObj.flush();//刷新
//使用close命令关闭资源的时候,colse会自动的先调用flush方法u触发刷新,以便让新的字节流能成功被写入.
outputStreamWriterObj.close();
//创建输入字节流
//InputStreamReader
InputStreamReader inputStreamReaderObj = new InputStreamReader(new FileInputStream("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"));
InputStreamReader inputStreamReaderObjAA = new InputStreamReader(new FileInputStream("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"), "GBK");//以编码形式
inputStreamReaderObj.close();
/*
void close() 关闭流并释放与之相关联的任何系统资源。
String getEncoding() 返回此流使用的字符编码的名称。
int read() 读一个字符
int read(char[] cbuf, int offset, int length) 将字符读入数组的一部分。 如果为读取全部,那么索引值为0.
boolean ready() 告诉这个流是否准备好被读取。
*/
//实现:复制一个文本内容到另一个文件中
InputStreamReader inputStreamReaderSuper = new InputStreamReader(new FileInputStream("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"));
OutputStreamWriter outputStreamWriterSuper = new OutputStreamWriter(new FileOutputStream("\\outputStreamWriterSuper.txt"));
//一次读取一组数组(数组长度中带有元素的数组)的字符数据,
char[] charParamTwo = new char[1024];
int len;
while((len = inputStreamReaderSuper.read(charParamTwo))!=-1){ // 此处len表示的时,长度为1024的数组'chaparamTwo'中有多少个数组填满了元素,如为500个,则read方法返回500个.
outputStreamWriterSuper.write(charParamTwo, 0, len); //len 和 length的区别,如果直接使用获取长度的length,则内容无区别,但是文件大小会大一点.
//如果为len,同样内容无区别,但文件大小会小一点.
}
outputStreamWriterSuper.close();
inputStreamReaderSuper.close();
}
}
public class BufferedReaderAndBufferedWrider {
public static void main(String[] args) throws IOException {
BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\bufferedWriterObj.txt"));//缓冲输出流
BufferedReader bufferedReaderObj = new BufferedReader(new FileReader("C:\\Users\\1\\Documents\\Tencent Files\\aaa.txt"));//缓冲输入流
//完成复制文件,其中要用到特有方法
//特有方法:
// bufferedReader String readLine() 一次只读取一行字符串。
//bufferedWriter ritervoid newLine() 写一行分隔符。
//bufferedWriter riter write() 一次写一个字符串
String temp;
while ((temp = bufferedReaderObj.readLine()) != null) {
bufferedWriterObj.write(temp);
bufferedWriterObj.newLine(); //用于文本中的换行符.它的作用是先判断获取到的该行字符串有没有换行符,
// 如果有,不论你是什么系统(系统不同,换行符也不同),都能将文本中的的隐性换行符给替代掉,用newLine表示换行.
//如果不用,写出的文件很可能缺失了原有的换行符.
bufferedWriterObj.flush();
}
bufferedWriterObj.close();
bufferedReaderObj.close();
}
要求:将集合中的数据写到硬盘文件中
public class BufferedReaderAndBufferedWrider {
public static void main(String[] args){
mapListOfIo();
}
public static void mapListOfIo() throws IOException {
Map<Integer, String> mapObj = new HashMap<>();
mapObj.put(1, "中国");
mapObj.put(2, "崛起");
mapObj.put(3, "国运");
mapObj.put(4, "昌隆");
Set<Integer> setMapObj = mapObj.keySet();//列出所有键
BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\bufferedWriterObjOfMapList.txt"));//缓冲输出流
for (Integer integer : setMapObj) {
String a = mapObj.get(integer);//根据键找到值
bufferedWriterObj.write(a);//写入
bufferedWriterObj.newLine();//换行
bufferedWriterObj.flush();//刷新
}
bufferedWriterObj.close();//释放资源
}
}
要求:将硬盘中的’中日文档案’文件写入到集合中,然后随机打印其中一个句子
public class BufferedReaderAndBufferedWrider {
public static void main(String[] args){
IoOfMapList();
}
public static void IoOfMapList() throws IOException {
BufferedReader bufferedReaderObj = new BufferedReader(new FileReader("\\MapListOfbufferedWriterObj.txt"));//缓冲输入流
ArrayList<String> arrayListObj = new ArrayList<>();
String a;
while ((a = bufferedReaderObj.readLine()) != null) {//如果缓冲输入流通过readLine获取到的某一行有内容,则进行循环.readLine获取到的内容会以String类型返回,
// 因此判断左侧的String变量'a'是否为空即可.
arrayListObj.add(a);
System.out.println("加入的元素为:" + a);
}
Random r = new Random();
int number = r.nextInt(arrayListObj.size());
System.out.println("随机元素为:" + arrayListObj.get(number));
}
}
要求:创建一个学生对象,将学生信息输出到一个硬盘文件中.格式:学号,姓名,年龄,地址
public class BufferedReaderAndBufferedWrider {
public static void main(String[] args){
studentInfoOfFile();
}
public static void studentInfoOfFile() throws IOException {
Student studentObj = new BufferedReaderAndBufferedWrider().new Student("10001","刘亦菲",26,"深圳");
Student studentObjTwo = new BufferedReaderAndBufferedWrider().new Student("10002","赵丽颖",21,"北京");
Student studentObjThree = new BufferedReaderAndBufferedWrider().new Student("10003","迪丽热巴",28,"上海");
Student studentObjFour = new BufferedReaderAndBufferedWrider().new Student("10001","刘若英",37,"广州");
BufferedWriter bufferedWriterObj = new BufferedWriter(new FileWriter("\\StudentInfo.txt"));
ArrayList<Student> arrayListObj = new ArrayList<>();
arrayListObj.add(studentObj);
arrayListObj.add(studentObjTwo);
arrayListObj.add(studentObjThree);
arrayListObj.add(studentObjFour);
for (Student student : arrayListObj) {
String studentInfo = "学号:"+student.getStudentNum()+" 姓名:"+student.getName()+" 年龄:"+student.getAge()+" 地址:"+student.getAddress();
bufferedWriterObj.write(studentInfo);
bufferedWriterObj.newLine();//换行符
bufferedWriterObj.flush();
}
bufferedWriterObj.close();
}
class Student{
private String studentNum;
private String name;
private int age;
private String address;
public String getStudentNum() {
return studentNum;
}
public void setStudentNum(String studentNum) {
this.studentNum = studentNum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Student() {
}
public Student(String studentNum, String name, int age, String address) {
this.studentNum = studentNum;
this.name = name;
this.age = age;
this.address = address;
}
}
}