java学习--字符流

字符流

为什么会出现字符流

字符流的介绍

​ 由于字节流操作中文不是特别方便,所以java提供字符流

​ 字符流=字节流+编码表

中文的字节存储方式

用字节流复制文本是,文本文件会有中文,汉子在存储时候,无论选择那种编码存储,第一个字节都是负数。

编码表

什么是字符集

  • 是一个系统支持的所有字符的集合,包括各国文字,标点符号,图形符号,数字等

    计算机要准确的存储和识别各种自己符号,就需要进行字符编码,一套字符集必然至少有一套字符编码,常见字符集有ASCll字符集,GBXXX字符集,Unicode字符集等

常见的字符集
  • ASCll字符集

    I是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键,推个,换行键等)和可现实字符(英文大小写字符,阿拉伯数字和西文符号)

    基本的ASCII字符集,使用7位表示一个字符,其扩展字符集使用8位表示一个字符,共256个字符,方便支持欧洲常用字符,是一个系统支持的所有字符的集合,包括个国家文字,标点符号,图形符号,数字等。

  • GBXXX字符集:

    GBK:最常用的中文码表。是在GB2312基础上的扩展规范,使用了双字节流编码方案,共收录了21001个汉字,完全兼容GB312标准,同时支持繁体汉字以及日韩文字等。

  • Unicode字符集

    UTF-8编码:可以用来表示UniCode标准中任意字符,他是电子邮件,网页及其他存储或传送文字应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有的互联网协议都必须支持UTF-8编码,他是用一至4个字节为每个字符编码

编码规则:

128个US-ASCLL字符,只需要一个字节编码

拉丁文等字符,需要两个字节编码

大部分常用字(含中文),使用三个字节编码

其他极少使用的UniCode辅助字符,使用四个字节编码

字符串中俄编码解码问题
方法名说明
byte[] getByte()使用平台的默认字符集将该String编码为一系列字节
byte[] getBytes(String charsetName)使用指定的字符集将String编码为一系列字节
String(byte[] bytes)使用平台的默认字符集解码指定的字节数组来创建字符集
String(byte[] bytes, String charsetName)通过指定的爱腹肌解码指定的字节数组来创建字符串

代码演示

public static void main(String[] args) throws UnsupportedEncodingException {
        String s="菲菲";
         byte [] bys=s.getBytes();
         byte [] by=s.getBytes("UTF-8");
         byte [] bytes=s.getBytes("GBK");
        System.out.println(Arrays.toString(bys));
        System.out.println(Arrays.toString(by));
        System.out.println(Arrays.toString(bytes));

        String ss=new String(bys);
        String ss1=new String(by,"UTF-8");
        String ss2=new String(bytes,"GBK");
        System.out.println(ss);
        System.out.println(ss1);
        System.out.println(ss2);
    }
字符流写数据
  • 介绍

    Writer:用于鞋服字符流的抽象父类

    FileWriter:用于写入字符流的常用子类

  • 构造方法

    方法名说明
    FileWriter(File file)根据给定的File对象构造一个FileWriter对象
    FileWriter(File file,boolean append)根据给定的File对象构造一个FileWriter对象
    FileWriter(String fileName)根据给定的文件名构造一个FileWriter对象
    FileWriter(String fileName,boolean append)根据给定的文件名以及指示是否附加写入数据的Boolean值来构造FIleWriter对象
  • 成员方法

    方法名说明
    void write()写一个字符
    void write(char[] cbuf)写入一个字符数组
    void write(char cbuf,int off,int len)写入字符数组的一部分
    void write(String str)写一个字符串
    void write(String str,int off,int len)写一个字符串的一部分
  • 刷新和关闭的方法

    方法名说明
    flush()刷新流,之后还可以继续写数据
    close()关闭流,释放资源,丹斯在关闭之后会刷新流,一旦关闭,就不能再写数据
  • 代码演示

    public static void main(String[] args) throws IOException {
            FileWriter fw=new FileWriter("E:\\Java\\IO\\practice\\java.txt");
            //写一个字符
            //fw.write(98);
    
            //写入一个字符串数组
            char [] chars={'I','c','h','L','i','e','b','e','D','i','s','h'};
            fw.write(chars);
    
            //写入一个字符串
            fw.write("Minaracastan Sinua");
    
            fw.close();
        }
    
字符流读数据
  • 介绍

    ​ Reader:用于读取字符流的抽象父类

    ​ FileReader:用于读取字符流的常用子类

  • 构造方法

    方法名说明
    FileReader(File file)在给定从中读取数据的File的情况下创建一个新的FileReader
    FileReader(String fileName)在给定从中读取数据的文件名的情况下创建一个新的FileReader
  • 成员方法

    方法名说明
    int read()一次读取一个字符数据
    int read(char[] cbuf)一次读取一个字符数组数据
  • 代码演示

    public static void main(String[] args) throws IOException {
            FileReader fr=new FileReader("E:\\Java\\IO\\practice\\java.txt");
            //一次读取一个数据
            int ch;
            while((ch=fr.read())!=-1){
                System.out.println((char)ch);
            }
            //一次读取一个字符数组
            char [] chars=new char[1024];
            int len;
            while((len=fr.read())!=-1){
                System.out.println(new String(chars,0,len));
            }
    
            fr.close();
        }
    
    字符流用户注册案例
    • 案例需求

      • 将键盘录入的用户名和密码保存到本地实现永久存储
    • 实现步骤

      • 获取用户输入的用户名和密码
      • 将用户输入的用户名和密码写入到本地的文件中
      • 关流释放资源
    • 代码实现

      public static void main(String[] args) throws IOException {
              Scanner sc=new Scanner(System.in);
              System.out.println("请输入用户名:");
              String username=sc.next();
              System.out.println("请输入密码:");
              String password=sc.next();
      
              FileWriter fw=new FileWriter("E:\\Java\\IO\\practice\\java1.txt");
              //写入信息
              fw.write(username);
              fw.write("\r\n");
              fw.write(password);
              //资源刷新
              fw.flush();
              //关闭流
              fw.close();
      
      
          }
      
字符缓冲流
  • 字符缓冲流介绍
    • ​ BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区的大小,或者可以接受默认大小,默认值足够大,可用于大多数用途
    • BufferedReader:从祖父输入流读取文本,缓冲字符,一提供字符,数组和行的高效读取,可以指定缓冲区的大小,默认值足够大,可用于大多数用途
  • 构造方法
    方法名说明
    BufferedWriter(Writer out)创建字符缓冲输出流对象
    BufferedReader(Reader in)创建字符缓冲输入流对象
  • 代码演示
    public static void main(String[] args) throws IOException {
            BufferedWriter bw=new BufferedWriter(new
                    FileWriter("E:\\Java\\IO\\practice\\java.txt"));
            bw.write("Ik hou van jou\r\n");
            bw.write("Minarastan Sinua");
            bw.close();
    
            //读取文件
    
            BufferedReader br=new BufferedReader(
                    new FileReader("E:\\Java\\IO\\practice\\java.txt"));
    
            //按字符数组读取
            char [] chars=new char[1024];
            int len;
            while((len=br.read())!=-1){
                System.out.print(new String(chars,0,len));
            }
            br.close();
        }
    
字符缓冲流特有功能
  • 方法介绍

    ​ BufferedWriter:

    方法名说明
    void newLine()写一行行分隔符,行分隔字符串有系统属性定义

    BufferedReader:

    方法名说明
    String readLine()读一行文字,结果包含行的内容的字符串,不包括任何终止字符如果流的结尾已经到达,则为null
  • 代码演示

public static void main(String[] args) throws IOException {
        //创建字符缓冲流
        BufferedWriter bw=new BufferedWriter(
                new FileWriter("E:\\Java\\IO\\practice\\java.txt"));

        //写数据
        for (int i = 0; i < 10; i++) {
            bw.write("Ich liebe Dish" +i);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();

        //创建字符缓冲输入流
        BufferedReader br=new BufferedReader(
                new FileReader("E:\\Java\\IO\\practice\\java.txt")
        );

        String line;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }

        //释放资源
        br.close();
    }
字符缓冲刘操作文件中数据排序案例
  • 案例需求

    • 使用字符缓冲流读取文件中的数据,排序后再次写到本地文件
  • 实现步骤

    • 将文件中的数据读取到程序中
    • 对读取到的数据进行处理
    • 将处理后的数据添加到集合中
    • 对集合中的数据进行排序
    • 将排序后的集合中的数据写入到文件中
  • 代码实现

    public static void main(String[] args) throws IOException {
            //读取文件
            BufferedReader br=new BufferedReader(
                    new FileReader("E:\\Java\\IO\\practice\\java.txt")
            );
            String line=br.readLine();
            System.out.println("读取到的数据为:"+line);
            br.close();
    
            //按照空格进行切割
            String [] split=line.split(" ");
    
            //把字符串类型的数据变成int类型
            int [] arr=new int[split.length];
            //遍历split数组,可以进行类型转换
            for (int i = 0; i < split.length; i++) {
                String smallStr=split[i];
                int number=Integer.parseInt(smallStr);
                arr[i]=number;
            }
    
            //排序
            Arrays.sort(arr);
            System.out.println(Arrays.toString(arr));
    
            //排序过后写入本地
            BufferedWriter bw=new BufferedWriter(
                    new FileWriter("E:\\Java\\IO\\practice\\java.txt"));
            for (int i = 0; i < arr.length; i++) {
                bw.write(arr[i]+" ");
                bw.flush();
            }
            bw.close();
    
        }
    

转换流

字符流中的编码解码问题两个相关的两个类
  • InputStreamReader:是从字节流到字符流的桥梁,父类是Reader,它读取字节,并使用指定的编码将其解码为字符

    它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集

  • OutputStreamWriter:是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节

    他使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集

转换流写数据

构造方法

方法名说明
InputStreamReader(InputStream in)使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in String chaset)使用指定的字符编码创建InputStreamReader对象
OutputStreamWriter(OutputStream out)使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String chartset)使用指定的字符编码创建OutputStreamWriter对象

代码演示

public static void main(String[] args) throws IOException {
        OutputStreamWriter osw=new OutputStreamWriter(
                new FileOutputStream("E:\\Java\\IO\\practice\\sinua.txt"));
        osw.write("Miluji te");
        osw.close();

        InputStreamReader isr=new InputStreamReader(
                new FileInputStream("E:\\Java\\IO\\practice\\sinua.txt"),"GBK");
        char [] chars=new char[1024];
        int length;
        while((length=isr.read())!=-1){
            System.out.println(new String(chars,0,length));

        }
        isr.close();
    }

对象操作流

对象序列化流
  • 对象序列化介绍

    • 对象序列化:将对象保存到磁盘中,或者在网络传输对象
    • 这种机智就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型,对象的数据和对象中存储的属性等信息
    • 字节序列写到文件后,相当于文件中持久保存了一个对象的信息
    • 反之, 该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
  • 对象序列化流:ObjectOutputStream

    • 将java对象的原始数据类型和图形写入OutputStream,可以使用ObjectInputStream读取(重构)对象。可以通过使用流的文件来实现对象的持久储存。如果是网络套接字流,则可以在另一进程中重构对象。
  • 构造方法

    方法名说明
    ObjectOutputStream(OutputStream out)创建一个写入指定的OutPutStream的ObjecdtOutputStream
  • 序列化对象方法

    方法名说明
    void writeObject(object obj)将指定的对象写入ObjectOutputStream
对象反序列化流
  • 对象反序列化流:ObjectInputStream

    • ObjectInputStream反序列化先前使用ObjectOuputStream编写的原始数据和对象
  • 构造方法

    方法名说明
    ObjectInputStream(InputStream in)创建从指定的InputStream读取的ObjectInputStream
  • 反序列化对象的方法

    方法名说明
    Object readObject()从ObjectInputStream读取一个对象

示例代码

OutputStreamWriter osw=new OutputStreamWriter(
                new FileOutputStream("E:\\Java\\IO\\practice\\sinua.txt"));
        osw.write("Miluji te");
        osw.close();

        InputStreamReader isr=new InputStreamReader(
                new FileInputStream("E:\\Java\\IO\\practice\\sinua.txt"),"GBK");
        char [] chars=new char[1024];
        int length;
        while((length=isr.read())!=-1){
            System.out.println(new String(chars,0,length));

        }
        isr.close();
    }
serivalVersionUID&transient
  • servalVersionUID

    • 用对象序列化流序列化了一个对象后,加入我们修改了对象所属的类的文件,读取数据会不会出现问题呢?

      • 会出问题,会抛出InvalidClassException异常
    • 如果出问题了,如何解决呢

      • 重新序列化

      • 给对象所属的类加一个servalVersionUID

        • private static final long servalVersionUID=42L;
    • transient

      • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现?

        • 给该成员变量加transient官架子修饰,该关键字标记的成员变量不参与序列化过程

    示例代码

    学生类

    public class Student implements Serializable {
        private static final long servalVersionUID=42L;
        private String name;
        //private int age;
        //不想年龄被序列化
        private transient int age;
    
        public Student() {
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    public class Test {
        public Test() throws IOException {
        }
    
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            write();
            read();
    
        }
    
        private static void write() throws IOException {
            ObjectOutputStream oos = new ObjectOutputStream(new
                    FileOutputStream("E:\\Java\\IO\\practice\\java1.txt"));
            Student s = new Student("佟丽娅", 30);
            oos.writeObject(s);
            oos.close();
        }
    
        private static void read() throws IOException, ClassNotFoundException {
            //反序列化
            ObjectInputStream ois=new ObjectInputStream(
                    new FileInputStream("E:\\Java\\IO\\practice\\java1.txt")
            );
            Object obj=ois.readObject();
            Student student=(Student) obj;
            System.out.println(student.getName());
            ois.close();
        }
    
    }
    

    Properties集合

    Properties作为Map集合的使用
    • Properties介绍

      • 是一个Map体系的集合类
      • Properties可以保存到流中或从流中加载
      • 属性列表中的每个键以及对应的值都是一个字符串
    • Properties的基本使用

       public static void main(String[] args) {
              Properties prop =new Properties();
              prop.put("法语","Je t'aime");
              prop.put("德语","Ich Liebe Dish");
              prop.put("芬兰","Minaracastan Sinua");
              prop.put("荷兰","Ik hou van jou");
              prop.put("捷克","Miluji te");
      
              Set<Map.Entry<Object, Object>> entries = prop.entrySet();
              for (Map.Entry<Object, Object> key : entries) {
                   String value=(String)prop.get(key);
                  System.out.println(key);
              }
      
      
          }
      
      Properties作为Map集合的特有方法
      • 特有方法

        方法名说明
        Object setProperty(String key,Strinfg value)设置集合的键和值,都是String类型,底层调用Hashtable方法put
        String getProperty(String key)使用此属性列表指定的键搜索属性
        Set stringProperty()从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串

        示例代码

        public static void main(String[] args) {
                Properties prop =new Properties();
                prop.put("法语","Je t'aime");
                prop.put("德语","Ich Liebe Dish");
                prop.put("芬兰","Minaracastan Sinua");
                prop.put("荷兰","Ik hou van jou");
                prop.put("捷克","Miluji te");
        
                System.out.println(prop.getProperty("芬兰"));
                System.out.println(prop.getProperty("捷克"));
        
                System.out.println(prop);
                Set<String> names = prop.stringPropertyNames();
                for (String name : names) {
        
                    String value=prop.getProperty(name);
                    System.out.println(name+","+value);
                }
        
        
        
            }
        
        Properties和IO流相结合的方法

        和IO结合的方法

        方法名说明
        void load(Reader reader)从输入字符流读取属性列表(键和元素对)
        void store(Writer writer, String comments)将此属性列表(键和元素对) 写入此Properties表中,意识和使用load(Reader)方法的格式写入输出字符流

        示例代码

        public class Exam3 {
            public static void main(String[] args) throws IOException {
        
                myLoad();
                //myStore();
        
            }
        
            private static void myStore() throws IOException {
                Properties prop=new Properties();
                prop.put("法语","Je t'aime");
                prop.put("德语","Ich Liebe Dish");
                prop.put("芬兰","Minaracastan Sinua");
                prop.put("荷兰","Ik hou van jou");
                prop.put("捷克","Miluji te");
        
                FileWriter fw=new FileWriter("E:\\Java\\IO\\practice\\java.txt");
                prop.store(fw,null);
                fw.close();
            }
        
            private static void myLoad() throws IOException {
                Properties prop =new Properties();
                FileReader fr=new FileReader("E:\\Java\\IO\\practice\\java.txt");
                prop.load(fr);
                fr.close();
                System.out.println(prop);
            }
        
        }
        
        
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值