黑马程序员—对象的序列化和字符编码以及21天视频中其他知识总结

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

一、             对象的序列化

 

Serializable

类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义

序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。

下面是Person实现序列化的实例:

class Person implements Serializable

{

    //序列化Person类,使其在持久化是唯一

    staticfinallongserialVersionUID = 42L;

    String name;

    intage;

    //contry的值是唯一的,实例化该类时无论contry参数被赋值为任何值时

    //contry的值是cn一直不会被改变

    static String contry = "cn";

    public Person(String name,int age,String contry)

    {

       this.name = name;

       this.age = age;

       this.contry = contry;

    }

    public String toString()

    {

       returnname+"--"+age+"--"+contry;

    }

}

 

二、             字符编码

通过向文本编辑软件中只单独输入“联通”引出了字符编码问题。

这个问题说明“联通”这两个汉字在编码时用的是txt文本编辑器默认的gbk编码,但是在解码时,解码程序把“联通”经gbk编码之后的字节码误认为是UTF-8,所以按照UTF-8的格式对其进行解码,所以就出错了。

下面通过程序实验“联通”的编码和解码:  

//创建字符串联通

       String str = "联通";

      

       //将字符串联通gbk编码表编码

       byte[] buf = str.getBytes("gbk");

      

       //输出编码后的二进制数据

       for(byte b : buf)

       {

           System.out.println(Integer.toBinaryString(b&255));

       }

 

  编码方式是程序中经常出错的地方,特别是在编写jsp代码和后台以及数据库交互时更容易出错。

三、             字节数组

ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组

 ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变字节长度的字节数组,这就是数据目的地。

 因为这两个流对象都操作的数组,并没有使用系统资源。 所以,不用进行close关闭

publicclass ByteArrayStreamDemo

{

    publicstaticvoid main(String[] args)

    {

       //数据源

       ByteArrayInputStream bis = new ByteArrayInputStream("skdjfkds".getBytes());

   

       //数据目的

       ByteArrayOutputStream bos = new ByteArrayOutputStream();

      

       int by = 0;

      

       while((by = bis.read())!=-1)

       {

           bos.write(by);

       }

      

       System.out.println(bos.size());

       System.out.println(bos.toString());

      

       //数组输出流的全部内容写入到指定的输出流参数中

       //bos.writeTo(new FileInputStream("..."));

    }

 

}

 

四、             对象流

ObjectOutputStream:

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

     如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。

      只能将支持 java.io.Serializable 接口的对象写入流中。

       

      writeObject() 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。

      可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。

 

  ObjectInputStream:

     ObjectInputStream 用于恢复那些以前序列化的对象。

     其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。

Object readObject()  从 ObjectInputStream 读取对象

 

publicclass ObjectStreamDemo

{

    publicstaticvoid main(String[] args) throws Exception

    {

       //writeobj();

       readobj();

    }

   

    publicstaticvoid readobj()throws Exception

    {

       //创建ObjectInputStream打开obj.txt文件

       ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));

   

       //ois流中获取Person对象

       Person p = (Person)ois.readObject();

      

       //打印对象信息

       System.out.println(p);

      

       //关闭流

       ois.close();

    }

   

    publicstaticvoid writeobj()throws Exception

    {

       //创建ObjectOutputStream对象,并打开一个文件流对象

       ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));

      

       //Person对象写入文件中

       oos.writeObject(new Person("zhangsna",20,"kr"));

      

       //关闭ObjectOutputStream

       oos.close();

    }

 

}

 

五、管道流

PipedInputStream:

     管道输入流应该连接到管道输出流;

     管道输入流提供要写入管道输出流的所有数据字节。

      通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。

     不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。

     管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。

 PipedOutputStream:

      可以将管道输出流连接到管道输入流来创建通信管道。

      管道输出流是管道的发送端。

       通常,数据由某个线程写入 PipedOutputStream 对象,并由其他线程从连接的 PipedInputStream 读取。

      不建议对这两个对象尝试使用单个线程,因为这样可能会造成该线程死锁。

使用管道流时,经常伴随使用多线程技术。因为管道流中是两个对象:写入流和读取流。这两个流要同时执行才能成功,所以要用多线程。

class Read implements Runnable

{

    private PipedInputStream in;

    Read(PipedInputStream in)

    {

       this.in = in;

    }

    publicvoid run()

    {

       try

       {

           //创建字节数组用来存放读取到的字节数据

           byte[] buf = newbyte[1024];

          

           //读取接收到的数据

           int len = in.read(buf);

          

           //将接收到的数据打印

           System.out.println(new String(buf,0,len));

          

           in.close();

          

       }

       catch(IOException e)

       {

           thrownew RuntimeException("管道流读取失败");

       }

      

    }

   

}

 

//写入流线程

class Write implements Runnable

{

    private PipedOutputStream out;

   

    Write(PipedOutputStream out)

    {

       this.out = out;

    }

    publicvoid run()

    {

       try

       {

           //向管道流中写数据

           out.write("管道流对接试验".getBytes());

          

           Thread.sleep(10000);

          

           //关闭管道流

           out.close();

          

       }

       catch(Exception e)

       {

           thrownew RuntimeException("管道流读取失败");

       }

      

    }

   

}

 

 

publicclass PipedStreamDemo

{

    publicstaticvoid main(String[] args) throws IOException

    {

       //创建读取管道流

       PipedInputStream in = new PipedInputStream();

      

       //创建写入管道流

       PipedOutputStream out = new PipedOutputStream();

      

       //将读取流和写入流连接

       in.connect(out);

      

       Read r = new Read(in);

       Write w = new Write(out);

      

       //线程启动

       new Thread(r).start();

       new Thread(w).start();

      

 

    }

 

}

 

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值