zoukankan      html  css  js  c++  java
  • 转换流、缓冲流

    转换流,,,,, 缓冲流,,,,,Properties类,,,,,序列化流与反序列化流

     

    转换流

    1.                OutputStreamWriter类

    它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。

    复制代码
    public static void writeCN() throws Exception {
            //创建与文件关联的字节输出流对象
            FileOutputStream fos = new FileOutputStream("c:\cn8.txt");
            //创建可以把字符转成字节的转换流对象,并指定编码
            OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
            //调用转换流,把文字写出去,其实是写到转换流的缓冲区中
            osw.write("你好");//写入缓冲区。
            osw.close();
        }
    复制代码

    2.                InputStreamReader类

    InputStreamReader 是字节流通向字符流的桥梁:它使用指定的字符编码表读取字节并将其解码为字符。

    它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

    复制代码
    public class InputStreamReaderDemo {
        public static void main(String[] args) throws IOException {
            //演示字节转字符流的转换流
            readCN();
        }
        public static void readCN() throws IOException{
            //创建读取文件的字节流对象
            InputStream in = new FileInputStream("c:\cn8.txt");
            //创建转换流对象 
            //InputStreamReader isr = new InputStreamReader(in);这样创建对象,会用本地默认码表读取,将会发生错误解码的错误
            InputStreamReader isr = new InputStreamReader(in,"utf-8");
            //使用转换流去读字节流中的字节
            int ch = 0;
            while((ch = isr.read())!=-1){
                System.out.println((char)ch);
            }
            //关闭流
            isr.close();
        }
    }
    复制代码

         缓冲流

    1                字节缓冲流

    字节缓冲流根据流的方向,共有2个

    l  写入数据到流中,字节缓冲输出流 BufferedOutputStream

    l  读取流中的数据,字节缓冲输入流 BufferedInputStream

    1.1    字节缓冲输出流BufferedOutputStream

    1.2    字节缓冲输入流 BufferedInputStream

    复制代码
    public static void main(String[] args) throws IOException {
        FileInputStream shuru=new FileInputStream("D:\表约束.wmv");
        //创建字节输出缓冲流
        BufferedInputStream bis=new BufferedInputStream(shuru);
        //创建字节输出流
        FileOutputStream shuchu=new FileOutputStream("D:\io0512\a\字符流.wmv");
        //创建字节输出
        BufferedOutputStream bos=new BufferedOutputStream(shuchu);
        //复制
        int len=0;
        while((len=bis.read())!=-1){
            bos.write(len);
        }
        bis.close();
        bos.close();
    }
    复制代码

    2                字符缓冲流

    l  字符缓冲输入流 BufferedReader

    l  字符缓冲输出流 BufferedWriter

    完成文本数据的高效的写入与读取的操作

        字符缓冲输出流 BufferedWriter

    l  方法:

    void newLine() 根据当前的系统,写入一个换行符

    复制代码
    public class BufferedWriterDemo {
        public static void main(String[] args) throws IOException {
            //创建流
            //基本字符输出流
            FileWriter fileOut = new FileWriter("file.txt");
            //把基本的流进行包装
            BufferedWriter out = new BufferedWriter(fileOut);
            //2,写数据
            for (int i=0; i<5; i++) {
                out.write("hello");
                out.newLine();
            }
            //3,关闭流
            out.close();
        }
    }
    复制代码

        字符缓冲输入流 BufferedReader

    l  方法

    public String readLine() 读取一个文本行,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

    复制代码
    public class BufferedReaderDemo {
        public static void main(String[] args) throws IOException {
            //1,创建流
            BufferedReader in = new BufferedReader(new FileReader("file.txt"));
            //2,读数据
            //一次一个字符
            //一次一个字符数组
            //一次读取文本中一行的字符串内容
            String line = null;
            while( (line = in.readLine()) != null ){
                System.out.println(line);
            }
            
            //3,关闭流
            in.close();
        }
    }
    复制代码

    文本复制,一个字符数组一个数组读

    复制代码
    public class Demo04 {
    public static void main(String[] args) throws IOException {
        //创建字符输入
        FileReader shuru=new FileReader("D:\io0512\utf-8.txt");
        BufferedReader br=new BufferedReader(shuru);
        FileWriter shuchu=new FileWriter("D:\io0512\a\utf-8.txt");
        BufferedWriter bw=new BufferedWriter(shuchu);
        int len=0;
        char[] ch=new char[2];
        while((len=br.read(ch))!=-1){
            bw.write(ch,0,len);
            bw.flush();
        }
        br.close();
        bw.close();
    }
    }
    复制代码

    一个字节一个字节复制

    复制代码
    public static void main(String[] args) throws IOException {
        FileInputStream shuru=new FileInputStream("D:\表约束.wmv");
        //创建字节输出缓冲流
        BufferedInputStream bis=new BufferedInputStream(shuru);
        //创建字节输出流
        FileOutputStream shuchu=new FileOutputStream("D:\io0512\a\字符流.wmv");
        //创建字节输出
        BufferedOutputStream bos=new BufferedOutputStream(shuchu);
        //复制
        int len=0;
        while((len=bis.read())!=-1){
            bos.write(len);
        }
        bis.close();
        bos.close();
    }
    }
    复制代码

    一行一行的读

    复制代码
    public static void main(String[] args) throws IOException {
        //chuang减字符输入流
        FileReader shuru=new FileReader("D:\io0512\utf-8.txt");
        
        BufferedReader br=new BufferedReader(shuru);
        FileWriter shuchu=new FileWriter("D:\io0512\utf-82.txt");
        BufferedWriter bw=new BufferedWriter(shuchu);
        //复制
        String len=null;
        while((len=br.readLine())!=null){//一行一行读
            bw.write(len);
            bw.newLine();//换行
            bw.flush();
        }
        br.close();
        bw.close();
    }
    复制代码

         流的操作规律

    IO流中对象很多,解决问题(处理设备上的数据时)到底该用哪个对象呢?  

    把IO流进行了规律的总结(四个明确):

    l  明确一:要操作的数据是数据源还是数据目的。

                       源:InputStream    Reader

                       目的:OutputStream Writer

    先根据需求明确要读,还是要写。

    l  明确二:要操作的数据是字节还是文本呢?

                       源:

                                字节:InputStream

                                文本:Reader

                       目的:

                                字节:OutputStream

                                文本:Writer

    已经明确到了具体的体系上。

    l  明确三:明确数据所在的具体设备。

                       源设备:

                                硬盘:文件  File开头。

                                内存:数组,字符串。

                                键盘:System.in;

                                网络:Socket

                       目的设备:

                                硬盘:文件  File开头。

                                内存:数组,字符串。

                                屏幕:System.out

                                网络:Socket

    完全可以明确具体要使用哪个流对象。

    l  明确四:是否需要额外功能呢?

                       额外功能:

                                转换吗?转换流。InputStreamReader OutputStreamWriter

                                高效吗?缓冲区对象。BufferedXXX

         InputStream

           FileInputStream

           BufferedInputStream

    OuputStream

       FileOutputStream

       BufferedOuputStream

    Writer

      OutputStreamWriter

         FileWriter

          BufferedWriter

    Reader

      InputStreamReader

         FileReader

     BufferedReader

                                    Properties类

    Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

    特点:

    1、Hashtable的子类,map集合中的方法都可以用。

    2、该集合没有泛型。键值都是字符串。

    3、它是一个可以持久化的属性集。键值可以存储到集合中,也可以存储到持久化的设备(硬盘、U盘、光盘)上。键值的来源也可以是持久化的设备。

    4、有和流技术相结合的方法。

    复制代码
    public static void main(String[] args) {
        //创建Pro集合
        Properties pro=new Properties();
        pro.put("a", "18");//存值
        pro.put("b", "16");
        System.out.println(pro.getProperty("a"));//输出18,取值
        System.out.println(pro.getProperty("b"));//输出16
    }
    复制代码

    复制代码
    public static void main(String[] args) throws IOException {
        Properties pro=new Properties();//创建Propertues对象
        pro.put("name","Amy");
        pro.put("age", "19");
    //明确properties的路径 FileOutputStream fos=new FileOutputStream("src/com/oracle/demo02/pro.properties",true); pro.store(fos, "");//注释,注释不写显示当前时间 }
    复制代码

    l  load(InputStream)  把指定流所对应的文件中的数据,读取出来,保存到Propertie集合中

    l  load(Reader) 

    l  store(OutputStream,commonts)把集合中的数据,保存到指定的流所对应的文件中,参数commonts代表对描述信息

    l  stroe(Writer,comments);

     

    load读取

                   

         序列化流与反序列化流

     创建对象的方式:一种是new,一种是对象序列化

    ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。

    序列化:将一个对象封装到文件中(ObjectOutputStream )

    复制代码
    //序列化
    public class Demo01 {//将一个对象封存到文件中
    public static void main(String[] args) throws IOException {
        //明确目的地
        FileOutputStream fos=new FileOutputStream("D:\io0512\person.txt");
        //创建序列化流
        ObjectOutputStream oos=new ObjectOutputStream(fos);
        oos.writeObject(new Person("张三",20));
        oos.close();
    }
    }
    复制代码

    反序列化:将封装好的文件读出来(ObjectInputStream)

    用于从流中读取对象的

    复制代码
    //反序列化
    public class Demo02 {//将封存的对向读回来
    public static void main(String[] args) throws ClassNotFoundException, IOException {
        //明确数据源
        FileInputStream fis=new FileInputStream("D:\io0512\person.txt");
        //创建反序列化流对象
        ObjectInputStream ois=new ObjectInputStream(fis);
        //读取对象
        Person p=(Person)ois.readObject();
        System.out.println(p);//打印存好的信息,Person【name=张三,age=18】
        ois.close();
    }
    }
    复制代码

    Person类

    复制代码
    public class Person implements Serializable{//序列化接口
    public static String name;//静态修饰不属于对象,属于类,不被序列化(序列化是对象)
    private transient int age;//不需要被序列化的属性可以加transient,就不被序列化,写的值就不能被读出来
    //定死uid的序列化号,保证txt和person里的序列号一致
    private static final long serialVersionUID=123L;//序列化号
    
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
    }
    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;
    }
    
    }
    复制代码

                    序列化接口

    当一个对象要能被序列化,这个对象所属的类必须实现Serializable接口。否则会发生异常NotSerializableException异常。

    同时当反序列化对象时,如果对象所属的class文件在序列化之后进行的修改,那么进行反序列化也会发生异常InvalidClassException。发生这个异常的原因如下:

    l  该类的序列版本号与从流中读取的类描述符的版本号不匹配

    l  该类包含未知数据类型

    l  该类没有可访问的无参数构造方法

    Serializable标记接口。该接口给需要序列化的类,提供了一个序列版本号。serialVersionUID. 该版本号的目的在于验证序列化的对象和对应类是否版本匹配。

     

                   瞬态关键字transient

    当一个类的对象需要被序列化时,某些属性不需要被序列化,这时不需要序列化的属性可以使用关键字transient修饰。只要被transient修饰了,序列化时这个属性就不会序列化了。

    同时静态修饰也不会被序列化,因为序列化是把对象数据进行持久化存储,而静态的属于类加载时的数据,不会被序列化。

     不被序列化就无法写入数据,读取到的是默认值

  • 相关阅读:
    解决端口被占用
    Oracle查询所有表的字段明细
    Spring cron表达式
    Java爬取12306余票
    Activiti工作流框架——快速上手
    ERROR 1045 (28000): Access denied for user 'xxx'@'localhost' (using password: YES)【奇葩的bug】
    一分钟学会JavaMail(假)__手动滑稽
    通过Servlet实现汉字验证码
    使用ServletContext对象读取资源文件
    编写一个简单的java服务器程序
  • 原文地址:https://www.cnblogs.com/marswenze/p/13426090.html
Copyright © 2011-2022 走看看