字符流:就是在字节流的基础上,加上编码,形成的数据流
字符流出现的意义:因为字节流在操作字符时,可能会有中文导致的乱码,所以由字节流引申出了字符流。
字符输入流:Reader
常用子类:FileReader
文件字符输入流常用方法:
read();
read(char[ ]);
read(char[ ] ,offset,len);
字符输出流: Writer
常用子类:文件字符输出流: Filewriter
文件字符输出常用方法:
writer();
writer(char[ ]);
writer(char[ ],offset,len);
writer(string);
flush()刷新缓冲区
注意:close()方法默认调用了flush()方法,但是flush()方法只刷新缓冲区,而close()还会关闭IO流
字符输入流代码示例:
1 import java.io.File;
2 import java.io.FileReader;
3 import java.io.IOException;
4
5 public class Demo5 {
6
7 public static void main(String[] args) throws IOException{
8 FileReader fr=new FileReader(new File("1.txt"));
9 char[] ca=new char[1024];
10 int count=0;
11 while((count=fr.read(ca))!=-1) {
12 System.out.println(new String(ca,0,count));
13 }
14 }
15 }
运行结果:
字符输出流代码示例:
1 import java.io.File;
2 import java.io.FileReader;
3 import java.io.FileWriter;
4 import java.io.IOException;
5
6 public class Demo6 {
7
8 public static void main(String[] args) throws IOException{
9 FileReader fr=new FileReader(new File("1.txt"));
10 FileWriter fw=new FileWriter(new File("2.txt"));
11 char[] ca=new char[1024];
12 int count;
13 while((count=fr.read(ca))!=-1) {
14 fw.write(ca,0,count);
15 }
16 fr.close();
17 fw.close();
18 }
19 }
执行结果:
字符流与字节流的区别:字符流虽然以字节流为基础创建的,但是字节流可以支持声音,视频,图片,文本等所有文件类型,而字符流只支持文本文件。
带缓冲区的字符流:
BufferedReader/BufferedWriter 带缓冲区的字符输入流与字符输出流。
带缓冲区的字符输入流:BufferedReader:常用方法:readLine() 读取一行,如果为文件末尾,返回值为null。
带缓冲区的字符输出流:BufferedWriter:常用方法:writer(string)将字符串写入 到输出流。 newLine()根据系统的行分割符进行换行。
BufferReader代码示例:
1 import java.io.BufferedReader;
2 import java.io.File;
3 import java.io.FileReader;
4 import java.io.IOException;
5
6 public class Demo7 {
7
8 public static void main(String[] args) throws IOException{
9 BufferedReader br=new BufferedReader(new FileReader(new File("1.txt")));
10 String value;
11 while((value=br.readLine())!=null) {
12 System.out.println(value);
13 }
14 br.close();
15 }
16 }
BufferedWriter代码示例:
1 import java.io.BufferedReader;
2 import java.io.BufferedWriter;
3 import java.io.FileReader;
4 import java.io.FileWriter;
5 import java.io.IOException;
6
7 public class Demo8 {
8
9 public static void main(String[] args)throws IOException {
10 BufferedWriter bw=new BufferedWriter(new FileWriter("3.txt"));
11 BufferedReader br=new BufferedReader(new FileReader("1.txt"));
12 String value="";
13 while((value=br.readLine())!=null) {
14 bw.write(value);
15 bw.newLine();
16 }
17 bw.close();
18 br.close();
19 }
20 }
编码与乱码:
乱码:编码与解码不一致,导致的乱码问题,每一种编码格式都有自己独特的编码,如果编码与解码不一致,势必会导致乱码,例如用Unicode编码,用gbk解码,就会字符与码值不匹配,从而导致乱码。
编码表:编码和解码使用的规则:
ASCII码:美国信息交换标准代码。单字节编码,不支持中文。
gbk:国标码;
Unicode/utf-8 :双字节编码,支持中文(万国码)
代码示例:
1 public class 读取不同编码的文本文件 {
2 public static void main(String[] args) throws IOException {
3 // BufferedReader br=new BufferedReader(new FileReader(new File("C:\\Users\\Administrator\\De
4 sktop\\6.txt")));
5 // 改进
6 BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\
7 \Users\\Administrator\\Desktop\\6.txt")),"gbk"));
8 String st = br.readLine();
9 System.out.println(st);
10 }
11 }
转换流
1.InputStreamReader 将字节流转换成字符流 输入
2.OutputStreamWriter 将字节流转换成字符流 输出
3. 构造方法:
① InputStreamReader(InputStream in)
② InputStreamReader(InputStream in, String cs)
③ OutputStreamWriter(OutputStream out)
④ OutputStreamWriter(OutputStream out, String charsetName)
4. 作用:
① 可以将字节流转换成字符流
② 可以使用指定的编码来读取或写入流。
代码示例:
1 public class 转换流 {
2 public static void main(String[] args) throws IOException {
3 InputStreamReader is=new InputStreamReader(new FileInputStream(new File("C:\\Users\\Administ
4 rator\\Desktop\\6.txt")),"gbk");
5 char[] c=new char[1024];
6 int value = is.read(c);
7 System.out.println(Arrays.toString(c));
8 }
9 }
字节数组字节输出流
ByteArrayOutputStream
字节数组字节输出流:
特点: 可以将数据写入到 byte 数组中,并且该缓冲区可以随着写入的数据而自增
① 构造方法 :
ByteArrayOutputStream()
② 注意:此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
③ 常用方法:
1 》 write(byte[]) 将 byte[] 中的值写入缓冲区字节数组,该缓冲区随着数据的增多而自增。
2 》 toString() 要想获取缓冲区的字节数据,可以通过该方法将其转换为字符串。
代码示例:
1 public class 字节数组字节输出流 {
2 public static void main(String[] args) throws IOException {
3 ByteArrayOutputStream bos = new ByteArrayOutputStream();
4 String s="abc";
5 byte[] b=s.getBytes();
6 System.out.println(Arrays.toString(b));
7 bos.write(b);
8 bos.write(b);
9 bos.close();
10 System.out.println(Arrays.toString(b));
11 System.out.println(bos.toString());
12 }
13 }
对象流 / 序列化与反序列化流
- 对象流 / 序列化流
ObjectInputStream: 反序列化流
② ObjectOutputStream: 序列化流
1 》常用方法:
writeObject(obj) 将 obj 对象写入到流中
readObject 读取流中的数据
① EOFException 表示读取流意外读到了文件的末尾 ( 就是一个空文件。 )
2 》构造方法
ObjectOutputStream(OutputStream out)
ObjectInputStream(InputStream in)
3 》序列化版本号:
serialVersionUID 序列化版本号:保证序列化流与反序列化流读写一致,保证版本一致性。
代码示例一:
1 public class 用序列化流与反序列化流操作集合 {
2 public static void main(String[] args) {
3 ArrayList<Teacher> list=new ArrayList<>();
4 list.add(new Teacher(" 张三 ", 18, new ClassRoom("0318java")));
5 list.add(new Teacher(" 李四 ", 18, new ClassRoom("0318java")));
6 list.add(new Teacher(" 王五 ", 18, new ClassRoom("0318java")));
7 // writeToFile(list,"stu.txt");
8 // 读取
9 System.out.println(readTeacher("stu.txt"));
10 }
11 // 带异常处理的 ,序列化
12 public static void writeToFile(ArrayList<Teacher> list,String fileName) {
13 // 序列化流进行写入
14 try(
15 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File(fileName)));
16 ){
17 oos.writeObject(list);
18 }catch (Exception e) {
19 e.printStackTrace();
20 }
21 }
22 // 反序列化
23 public static ArrayList<Teacher> readTeacher(String fileName) {
24 ArrayList<Teacher> list=null;
25 // 反序列化流读取文件中的集合
26 try(
27 ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File(fileName)));
28 ){
29 list = (ArrayList<Teacher>) ois.readObject();
30 }catch (Exception e) {
31 e.printStackTrace();
32 }
33 return list;
34 }
35 }
36 class Teacher implements Serializable{
37 /**
38 * 序列化版本号:默认版本号为 1l
39 */
40 private static final long serialVersionUID = 1L;
41 private String name;
42 private int age;
43 private ClassRoom cn;// 班级
44 public String getName() {
45 return name;
46 }
47 public void setName(String name) {
48 this.name = name;
49 }
50 public int getAge() {
51 return age;
52 }
53 public void setAge(int age) {
54 this.age = age;
55 }
56 public ClassRoom getCn() {
57 return cn;
58 }
59 public void setCn(ClassRoom cn) {
60 this.cn = cn;
61 }
62 @Override
63 public String toString() {
64 return "Teacher [name=" + name + ", age=" + age + ", cn=" + cn + "]";
65 }
66 public Teacher() {
67 super();
68 // TODO Auto-generated constructor stub
69 }
70 public Teacher(String name, int age) {
71 super();
72 this.name = name;
73 this.age = age;
74 }
75 }
76 public Teacher(String name, int age, ClassRoom cn) {
77 super();
78 this.name = name;
79 this.age = age;
80 this.cn = cn;
81 }
82 }
83 class ClassRoom implements Serializable{
84 /**
85 * 序列化版本号:保证序列化流与反序列化流读写一致
86 */
87 private static final long serialVersionUID = 3359646767342429683L;
88 private String no;
89 public ClassRoom() {
90 super();
91 // TODO Auto-generated constructor stub
92 }
93 public ClassRoom(String no) {
94 super();
95 this.no = no;
96 }
97 @Override
98 public String toString() {
99 return "ClassRoom [no=" + no + "]";
100 }
101 public String getNo() {
102 return no;
103 }
104 public void setNo(String no) {
105 this.no = no;
106 }// 班级号码
107 }
代码示例二:
1 import java.io.File;
2 import java.io.FileInputStream;
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.ObjectInputStream;
6 import java.io.ObjectOutputStream;
7 import java.io.Serializable;
8 import java.util.ArrayList;
9 import java.util.Iterator;
10
11 public class Demo9 {
12
13 public static void main(String[] args)throws IOException, Exception {
14 ArrayList<Student6> list=new ArrayList<>();
15 list.add(new Student6("张三","1001",18));
16 list.add(new Student6("李四","1002",19));
17 list.add(new Student6("王五","1003",20));
18 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File("4.txt")));
19 oos.writeObject(list);
20 oos.close();
21
22 ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("4.txt") ));
23 ArrayList<Student6> list2=(ArrayList<Student6>) ois.readObject();
24 Iterator<Student6> it=list2.iterator();
25 while(it.hasNext()) {
26 Student6 stu=it.next();
27 System.out.println("姓名:"+stu.getName()+"\t学号:"+stu.getStuNo()+"\t年龄+\t:"+stu.getAge());
28 }
29 }
30 }
31 class Student6 implements Serializable{
32 /**
33 *
34 */
35 private static final long serialVersionUID = 2658878058482366562L;
36 private String name;
37 private String stuNo;
38 private int age;
39
40 public Student6() {
41 super();
42 }
43 public Student6(String name,String stuNo,int age) {
44 this.name=name;
45 this.stuNo=stuNo;
46 this.age=age;
47
48 }
49 public void setName(String name) {
50 this.name=name;
51 }
52 public String getName() {
53 return name;
54 }
55 public void setStuNo(String stuNo) {
56 this.stuNo=stuNo;
57 }
58 public String getStuNo() {
59 return stuNo;
60 }
61 public void setAge(int age) {
62 this.age=age;
63 }
64 public int getAge() {
65 return age;
66 }
67 @Override
68 public String toString() {
69 return "Student6 [name=" + name + ", stuNo=" + stuNo + ", age=" + age + "]";
70 }
71 }
EOFException表示输入过程中意外地到达文件尾或流尾的信号
字符流写入 要刷新/关流才能写入(刷新也是调用了flush(刷新)方法)
就像水龙头带软管,开水龙头要等一会儿水才能流出来,就和需要刷新一样
字节流不需要刷新,是因为字节流是一个字节一个字节读和写的,而字符流是三个字节或者两个字节读和写的,所以
字符流需要刷新,而字节流不需要刷新