----------- 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学习型技术博客、期待与您交流! ------------