• 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()+"	学号:"+stu.getStuNo()+"	年龄+	:"+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(刷新)方法)
    就像水龙头带软管,开水龙头要等一会儿水才能流出来,就和需要刷新一样

    字节流不需要刷新,是因为字节流是一个字节一个字节读和写的,而字符流是三个字节或者两个字节读和写的,所以
    字符流需要刷新,而字节流不需要刷新

  • 相关阅读:
    layoutSubviews总结
    Vue.js:循环语句
    Vue.js:条件与循环
    Vue.js:模版语法
    Vue.js:起步
    Vue.js-Runoob:目标结构
    Vue.js-Runoob:安装
    Runoob-Vue.js:教程
    Vue.js:template
    培训-Alypay-Cloud:蚂蚁金融云知识点
  • 原文地址:https://www.cnblogs.com/ywzbky/p/10697414.html
Copyright © 2020-2023  润新知