• I/O操做总结(四))


    前面已经把java io的主要操作讲完了

    这一节我们来说说关于java io的其他内容

    Serializable序列化

    实例1:对象的序列化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
     
    @SuppressWarnings("serial")
    //一个类要想实现序列化则必须实现Serializable接口
    class Person implements Serializable {
        private String name;
        private int age;
         
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
         
        public String toString() {
            return "Name:" this.name + ", Age:" this.age;
        }
    }
     
    public class Demo {
        public static void main(String[] args) {
            String path = File.separator + "home" + File.separator + "siu" +
                          File.separator + "work" + File.separator + "demo.txt";
             
            Person p1 = new Person("zhangsan",12);
            Person p2 = new Person("lisi",14);
             
            //此处创建文件写入流的引用是要给ObjectOutputStream的构造函数玩儿
            FileOutputStream fos = null;
            ObjectOutputStream oos = null;
            try {
                fos = new FileOutputStream(path);
                oos = new ObjectOutputStream(fos);
                 
                //这里可以写入对象,也可以写入其他类型数据
                oos.writeObject(p1);
                oos.writeObject(p2);
            catch (IOException e) {
                e.printStackTrace();
            finally {
                try {
                    oos.close();
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    所谓对象序列化就是把一个对象进行持久化存储,方便保留其属性

    通俗点说,等于把一个对象从堆内存里边揪出来放到硬盘上

    当然,如果你开心,你可以序列化其他东西,包括数组,基本数据类型等等

    来看看内容,神马玩意儿这是……

    实例2:对象的反序列化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
     
    public class Demo {
        public static void main(String[] args) {
            String path = File.separator + "home" + File.separator + "siu" +
                          File.separator + "work" + File.separator + "demo.txt";
             
            //好吧,这里代码写得着实有点长了,还要抛异常什么的
            //如果你也看的烦,那就在主方法上抛吧,构造方法里用匿名对象就好了
            //什么?别告诉我你不知道匿名对象
            FileInputStream fis = null;
            ObjectInputStream ois = null;
            try {
                fis = new FileInputStream(path);
                ois = new ObjectInputStream(fis);
                 
                //这里返回的其实是一个Object类对象
                //因为我们已知它是个Person类对象
                //所以,就地把它给向下转型了
                Person p = (Person)ois.readObject();
                System.out.println(p);
                 
                //抛死你,烦烦烦~!!!
            catch (IOException e) {
                e.printStackTrace();
            catch (ClassNotFoundException e) {
                e.printStackTrace();
            finally {
                try {
                    //还是要记得关闭下流
                    ois.close();
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    你看,我们把一个对象存放在硬盘上是为了方便日后使用

    现在用得着它了,自然得拿出来

    管道流

    实例3:线程的通信

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    import java.io.IOException;
    import java.io.PipedInputStream;
    import java.io.PipedOutputStream;
     
    //实现Runnable接口,实现一个读的线程
    class Read implements Runnable {
        private PipedInputStream in;
        //将需要读的管道流传入到构造函数中
        public Read(PipedInputStream in) {
            this.in = in;
        }
         
        //实现读这一线程
        public void run() {
            try {
                byte[] buf = new byte[1024];
                int temp = 0;
                //循环读取
                //read是一个阻塞方法,需要抛异常
                //此处把打印流的代码也加入进来
                //是因为如果没有读取到数据,那么打印的代码也无效
                while((temp = in.read(buf)) != -1) {
                    String str = new String(buf,0,temp);
                    System.out.println(str);
                }
            catch (IOException e) {
                //其实这里应抛出一个自定义异常的
                //暂时我还没弄清楚
                e.printStackTrace();
            finally {
                try {
                    //我已经抛火了,这只是为了提醒自己异常很重要
                    in.close();
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }  
    }
     
    //这里实现一个写的类
    class Write implements Runnable {
        private PipedOutputStream out;
        //将管道输入流传进来
        public Write(PipedOutputStream out) {
            this.out = out;
        }
     
        public void run() {
            try {
                //这里开始写出数据
                out.write("管道输出".getBytes());
            catch (IOException e) {
                e.printStackTrace();
            finally {
                try {
                    //其实应该可以把这个关闭方法写到上面那个try里边
                    //但是这样感觉怪怪的,逻辑不大对
                    out.close();
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
     
    public class Demo {
        public static void main(String[] args) {
            PipedInputStream in = new PipedInputStream();
            PipedOutputStream out = new PipedOutputStream();
            try {
                //连接管道
                in.connect(out);
                 
                //创建对象,开启线程
                //此处同样放进try...catch里面
                //因为如果没有链接管道,下面操作无意义
                Read r = new Read(in);
                Write w = new Write(out);
                //把已经实现好run方法的对象放入线程中执行
                new Thread(r).start();
                new Thread(w).start();
                 
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

     好吧,废了那么大劲儿,就打印了这么一句话,异常抛弃来很烦,为了注重细节……

    管道流也许很难理解,其实非也

    我们知道,字节流和字符流都需要数组来进行流的中转

    而管道流则直接串联两条流,一边发送数据,一边接收

    然而,同时通信的的两种状态,如何才能确定发送和接收的一致性呢

    那么,就需要用到线程,无论是接收方还是发送方先执行

    总会造成一个线程的阻塞状态,从而等待另一方的数据传过来

    总体而言,管道流的目的,也就是为了线程通信

    此外,还有PipedReader和PipedWriter类,操作原理都一样,这里就不再赘述了

    DataOutputStream和DataInputStream类

    实例4:基本数据类型的写入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
     
    public class Demo {
        public static void main(String[] args) {
            String path = File.separator + "home" + File.separator + "siu" +
                          File.separator + "work" + File.separator + "demo.txt";
             
            DataOutputStream d = null;
                try {
                    //此处需要传入一个OutputStream类的对象
                    d = new DataOutputStream(new FileOutputStream(path));
                    //开始写入基本数据类型
                    d.writeInt(12);
                    d.writeBoolean(true);
                    d.writeDouble(12.2223);
                    d.writeChar(97);
                    //刷新流
                    d.flush();
         
                catch (IOException e) {
                    e.printStackTrace();
                finally {
                    try {
                        d.close();
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        }
    }

    此处我们并不能直观看懂内容,因为它采用字节流的方式操作,而不是字符流

    我们只需要知道,此程序已经将基本数据类型写入到硬盘即可

    实例5:基本数据类型的读取

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
     
    public class Demo {
        public static void main(String[] args) {
            String path = File.separator + "home" + File.separator + "siu" +
                          File.separator + "work" + File.separator + "demo.txt";
             
            DataInputStream d = null;
                try {
                    d = new DataInputStream(new FileInputStream(path));
                    //按存储顺序读取基本数据类型
                    System.out.println(d.readInt());
                    System.out.println(d.readBoolean());
                    System.out.println(d.readDouble());
                    System.out.println(d.readChar());
                     
                catch (IOException e) {
                    e.printStackTrace();
                finally {
                    try {
                        d.close();
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        }
    }

     这里要注意的是,一定要按照写入顺序读取,否则会发生数据的打印错误

  • 相关阅读:
    SqlDependency和SqlCacheDependency的若干说明
    sublime 3 随笔
    [有得]解决redmine写操作很慢的问题
    Java双重循环
    使用 Docker 打包 Rust Web 服务
    Centos8.3、hadoop-2.6.4 简单的日志分析实验
    广域网数据交换的三种方式
    计算机的起源与发展
    推荐两款生成数据库表结构说明文档工具
    Centos8.3、docker部署springboot项目实战记录
  • 原文地址:https://www.cnblogs.com/jmsjh/p/7504568.html
Copyright © 2020-2023  润新知