• 标准流与序列化


    1.标准输入输出流

    1.1 标准输入流

    源数据源是标准输入设备(键盘、鼠标、触摸屏)等输入设备。在java中用System.in 得到一个InputStream字节输入流。

    需求:在控制台输入一句话,然后原样输出

     1 public static void main(String[] args) throws IOException {
     2         // 需求:输入一句话,然原样输出
     3         InputStream in = System.in;
     4         
     5         byte[] buf = new byte[1024];
     6         int len;
     7         // buf中包含回车和换行
     8         len = in.read(buf);
     9         
    10         String str = new String(buf, 0, len);
    11         // System.out.println(Arrays.toString(buf));
    12         System.out.println(str);
    13     }

    注意:

    [1] 标准输入流以字节流流入内存,如果在控制台中输入字符,字符以默认编码(win简体:gbk)编码成字节进入标准输入流。

     1 public static void main(String[] args) throws IOException {
     2         // 需求:从控制台高效读取一行数据。把一首诗写入文件。
     3         
     4         InputStream in = System.in;
     5         InputStreamReader reader = new InputStreamReader(in, "GBK");
     6         BufferedReader br = new BufferedReader(reader);
     7         
     8         File file = new File("d:\javatest\k.txt");
     9         FileWriter writer = new FileWriter(file);
    10         BufferedWriter bw = new BufferedWriter(writer);
    11         
    12         String end = "bye";
    13         while(true) {
    14             String line = br.readLine();
    15             if(line.equals(end)) {
    16                 break;
    17             }
    18             
    19             bw.write(line);
    20             // bw.newLine();
    21         }
    22         
    23         bw.flush();
    24         
    25         bw.close();
    26         writer.close();
    27         
    28     }

    1.2  标准输出流(PrintStream)

    数据目的地是标准输出设备(显示器)等输出设备。在java中用System.out得到一个PrintStream 字节输出流(字节打印流)。提供了更强大的

    print

    println

    打印方法用于打印各种数据类型。

    需求:读取文件,显示到标准输出设备

     1 public static void main(String[] args) throws IOException {
     2         
     3         File file = new File("d:\javatest\k.txt");
     4         
     5         FileReader reader = new FileReader(file);
     6         BufferedReader br = new BufferedReader(reader);
     7         
     8         PrintStream ps = System.out;
     9         
    10         String line;
    11         while( (line=br.readLine())!=null ) {
    12             ps.println(line);
    13         }
    14     }

    PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。

     1 public static void main(String[] args) throws IOException {
     2         
     3         
     4         String str = "hello中国";
     5         byte[] buf = str.getBytes("utf-8");
     6         
     7         PrintStream ps = System.out;
     8         ps.write(buf);
     9         
    10     }

    2.序列化

    把内存中的对象永久保存到硬盘的过程称为对象序列化,也叫做持久化。

    把硬盘持久化的内存恢复的内存的过程称为对象反序列化。

    2.1 Serializable

    类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化,并抛出异常

    1 Exception in thread "main" java.io.NotSerializableException: cn.sxt05.serializable.Student
    2     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    3     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    4     at cn.sxt05.serializable.Test01.main(Test01.java:22)

    Serializable接口没有方法或字段,仅用于标识可序列化的语义

    public class Student implements Serializable{
    

    2.2 序列化对象

    ObjectOutputStream 继承于OutputStream,专门用于把对象序列化到本地。提供了

    writeXXX

    writeObject() 用于写入一个对象

     1 public static void main(String[] args) throws IOException {
     2         
     3         Student stu = new Student("001", "大狗", 20, Gender.男);
     4         
     5         /**
     6          *    方案1:取stu所有的属性,通过特定的字符串(-),把各个属性值连接起来
     7          *  001-大狗-20-男
     8          */
     9         
    10         File file = new File("d:\javatest\l.txt");
    11         FileOutputStream out = new FileOutputStream(file);
    12         ObjectOutputStream oos = new ObjectOutputStream(out);
    13         
    14         oos.writeObject(stu);
    15         
    16         oos.close();
    17         out.close();
    18     }

    2.3 序列化对象

    ObjectInputStream 继承于InputStream ,专门用于把本地持久化内容反序列化到内存,提供了

    readXXX

    readObject() 用于读取一个序列化内容并返回一个对象。

     1 public static void main(String[] args) throws IOException, ClassNotFoundException {
     2         
     3         File file = new File("d:\javatest\l.txt");
     4         
     5         
     6         FileInputStream in = new FileInputStream(file);
     7         ObjectInputStream ois = new ObjectInputStream(in);
     8         
     9         Student student = (Student) ois.readObject();
    10         System.out.println(student.getId());
    11         System.out.println(student.getName());
    12         System.out.println(student.getAge());
    13         System.out.println(student.getGender());
    14         
    15         ois.close();
    16         in.close();
    17     }

    2.4 序列化版本

    当序列化完成后,后期升级程序中的类(Student),此时再反序列化时会出现异常。

    1 Exception in thread "main" java.io.InvalidClassException: cn.sxt05.serializable.Student; local class incompatible: stream classdesc serialVersionUID = -6288733824962181189, local class serialVersionUID = 1690603786167234505
    2     at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)
    3     at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1876)
    4     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1745)
    5     at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2033)
    6     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1567)
    7     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427)
    8     at cn.sxt05.serializable.Test02.main(Test02.java:16)

    异常原因:序列化流的serialVersionUID和升级后类的版本不匹配。

    解决方案:给Student类加序列化版本号,有两种方式

    default serial version ID 生成默认的serial version ID 一般值都是1L。

    generated serial version ID 根据当前类的属性、方法生成一个唯一ID。

    1 public class Student implements Serializable {
    2 
    3     private static final long serialVersionUID = -1003763572517930507L;

    2.5 transient

    开发过程中,如果想忽略某些字段不让其序列化时,可以使用transient修饰。

    1 public class Student implements Serializable {
    2 
    3     private static final long serialVersionUID = 7222966748321328300L;
    4 
    5     private String id;
    6     private transient String name;
    7     private transient int age;
    8     private Gender gender;
    9     private String phone;

    3. DataInputStream/DataOutputStream

    DataOutputStream 继承OutputStream,专门用于把基本java数据类型写入输出流。提供了writeXXX 写入基本java数据类型。

    DataInputStream 继承于InputStream,允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。

    DataInputStream/DataOutputStream 特别适合读取/写入在网络传输过程中的数据流。

    写入基本java数据类型

     1 public static void main(String[] args) throws IOException {
     2         
     3         File file = new File("d:\javatest\n.txt");
     4         FileOutputStream out= new FileOutputStream(file);
     5         DataOutputStream dos = new DataOutputStream(out);
     6         
     7         dos.writeInt(10);
     8         dos.writeUTF("hello中国");
     9         
    10         dos.close();
    11         out.close();
    12         
    13         System.out.println("写入完成");
    14         
    15     }

    读取基本java数据类型

     1 public static void main(String[] args) throws IOException {
     2         
     3         File file = new File("d:\javatest\n.txt");
     4         FileInputStream in = new FileInputStream(file);
     5         DataInputStream dis = new DataInputStream(in);
     6         
     7         int a = dis.readInt();
     8         String str = dis.readUTF();
     9         
    10         System.out.println(a);
    11         System.out.println(str);
    12         
    13     }

    流的系统分类

     

  • 相关阅读:
    System.ServiceModel.CommunicationException:The underlying connection was closed: The connection was closed unexpectedly
    研究jBPM和NetBPM
    研究:Microsoft Solution Framework
    iOS银联,支付宝,微信,ping++开发文档
    Xampp+Openfire+Spark的简单使用
    ObjectiveC与Swift混编
    网络抓包教程
    iOS版微信开发小结(微信支付,APP跳转微信公众号)
    七牛上传图片问题总结
    2012年之总结
  • 原文地址:https://www.cnblogs.com/xfbb/p/10828923.html
Copyright © 2020-2023  润新知