黑马程序员-对象的序列化和管道流

 

----------- android培训java培训java学习型技术博客、期待与您交流! ------------ 

 

 

对象的序列化

ObjectInputStream
ObjectOutputStream

对象存放在堆内存中,当程序用完,内存释放,对内存垃圾回收,对象不存在了

而ObjectOutputStream可以将对内存中的对象存放在硬盘上,即使程序结束,对象仍然能读取(对象的实体化存储)

 

ObjectOutputStream(OutputStream out);
构造时,必须有一个目的


write(int val)
写入一个字节(存放最低8位)
writeInt(intval)
写入一个32位的int值(四个8位都存放起来)

 

//将一个对象存放到文件中
import java.io.*;
class ObjectStreamDemo
{
 public static void main(String[] args) throws IOException
 {
  writeObj();
 }
 public static void writeObj() throws IOException
{
ObjectOUtputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi",39));
oos.close();
}
}

 


//造一个对象
class Person
{
 String name;
 int age;
 Person(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
 public String toString()
 {
  return name+":"+age;
 }
}

 

直接这样会发生异常,需要实现接口,具备序列化功能。
需要导入包,实现接口,并覆盖方法;
(每一个类被序列化时,都有ID标识,long型,用来确定是否为同一个类)

 


import java.io.*;
class Person implements Serisalizable
//没有方法的接口,标记接口
{
 public static final long serialVersionUID = 42L;

 String name;
 int age;
 Person(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
 public String toString()
 {
  return name+":"+age;
 }
}

 


接下来需要读取该对象:

抛出Exception

main中writeObj();替换成readObject();

public static void readObj()
{
 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
 Person p = (Person)ois.readObject();
//会自动记录,依次读取下一个对象

 System.out.println(p);
 ois.close();
}

读取时不需要再赋值,直接用就可以了。

 


修改Person源文件后,由于序列号不对应,之前存储的Person对象无法读取。

自定义uid,则即使类文件改变,依旧可以读取。
eg:
public static final 龙 serialVersionUID = 42L;

注意:
静态不能被序列化。(静态在方法区中,对象存放在堆内存中)
若对非静态成员也不想序列化,保证其值在对内存中存在,而不在文件中存在,可以加上关键字:
transient

另:一般不存成txt,因为没必要看,也看不懂。例如可以存成Person.object

 


(管道流)

RandomAccessFile
随机访问文件,自身具备读写的方法。

通过skipBytes(int x),seek(int x)来达到随机访问

管道流
PipedInputStream 和 PipedOutputStream
输入输出可以直接进行连接,通过结合线程使用。


读取流和写入流需要一个中转站,而管道流可以对接到一起。

 

那么如何保证输入输出的顺序呢?
通常,数据由某个线程从PipedInputStream对象中读取,并由其他线程将其写入到相应的PipedOutputStream。不建议对这两个对象尝试使用单个线程,可能会造成死锁。

 

集合当中涉及到IO流的是Properties
IO流当中涉及到多线程的是管道流

 

然而输入输出是如何连接的呢?
要么直接在创建构造函数时,传入输出流:
PipedInputStream(PipedOutputStream src)

要么创建空构造函数,通过对象中方法来实现对接:
void connect(PipedOutputStream src);

 


import java.io.*;

class Read implements Runnable
{
 private PipedInputStream in;
 Read(PipedInputStream in)
 {
  this.in = in;
 }
 public void run()
 {
  try
  {
   byte[] buf = new byte[1024];

   System.out.println("读取前。。没有数据阻塞");
   int len = in.read(buf);
   System.out.println("读到数据。。阻塞结束");

 

   String s= new String(buf,0,len);

   System.out.println(s);

   in.close();

  }
  catch (IOException e)
  {
   throw new RuntimeException("管道读取流失败");
  }
 }
}

class Write implements Runnable
{
 private PipedOutputStream out;
 Write(PipedOutputStream out)
 {
  this.out = out;
 }
 public void run()
 {
  try
  {
   System.out.println("开始写入数据,等待6秒后。");
   Thread.sleep(6000);
   out.write("piped lai la".getBytes());
   out.close();
  }
  catch (Exception e)
  {
   throw new RuntimeException("管道输出流失败");
  }
 }
}

class  PipedStreamDemo
{
 public static void 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();


 }
}

 

 

----------- android培训java培训java学习型技术博客、期待与您交流! ------------ 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值