JAVA中字符流詳解


字符流:就是在字節流的基礎上,加上編碼,形成的數據流

字符流出現的意義:因為字節流在操作字符時,可能會有中文導致的亂碼,所以由字節流引申出了字符流。

字符輸入流: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 }

 

對象流 / 序列化與反序列化流
1. 對象流 / 序列化流
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(刷新)方法)
就像水龍頭帶軟管,開水龍頭要等一會兒水才能流出來,就和需要刷新一樣

字節流不需要刷新,是因為字節流是一個字節一個字節讀和寫的,而字符流是三個字節或者兩個字節讀和寫的,所以
字符流需要刷新,而字節流不需要刷新

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM