Java——IO系统概览 (8)

Java——IO系统概览

内存映射文件

大多数操作系统都可以利用虚拟内存实现来将一个文件或者文件的一部分“映射”到内存中。然后,这个文件就可以当做内存数组一样地访问,这比传统的文件操作要快的多。java.nio包中使得内存映射使用变得十分简单,我们若是要使用则先获得一个文件上的通道,然后调用map()产生mappedByteBuffer,这是一种特殊类型的直接缓冲器,还需要指定映射文件的初始位置和映射区域的长度,这也就说明我们可以只映射某个大文件的一小部分。

public class LargeMappedFiles { static int lenght = 0x8FFFFFF; //128MB public static void main(String[] args) throws Exception{ MappedByteBuffer out = new RandomAccessFile("test.txt", "rw"). getChannel().map(FileChannel.MapMode.READ_WRITE, 0, lenght); for(int i=0; i<lenght; i++) { out.put((byte)'x'); } System.out.println("Finished writing"); for(int i=lenght/2; i<lenght/2+6; i++) { System.out.println((char)out.get(i)); } } } 对象序列化

我们有时候会想将程序运行过程中的对象保存下来,等下一次运行程序时就可以被重建并且拥有拥有和它上一次相同的信息。Java的对象序列化就可以帮我们实现这些。Java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并且能够在以后将这个字节序列完全恢复为原来的对象。这一过程甚至可以通过网络进行,这也意味着序列化机制能够自动弥补不同操作系统之间的差异。

对象序列化是一项非常有趣的技术,它可以实现轻量级持久性(lightweight persistence)。"持久性"意味着一个对象的生命周期并不取决于程序是否正在执行;它可以生存在程序的调用之间。通过将一个序列化对象写入磁盘,然后在重新调用程序时恢复该对象,就可以实现持久性的效果。对象在程序中必须显示地序列化和反序列化还原。如果需要一个更严格的持久性机制,可以考虑Hibernate之类的工具。

对象序列化出现的原因主要是为了支持两种特性:

Java的远程方法调用(Remote Method Invocation, RMI),它使存活于其他计算机上的对象使用起来就像是存活在本机上一样。

对于Java Beans,对象的序列化也是需要的。使用一个Beans时,一般情况下是在设计阶段对它的状态信息进行配置。这种状态信息必须保存下来,并在程序启动时进行后期恢复;这种具体的工作就是由对象序列化完成的。

如何序列化和反序列化一个对象

序列化:首先该对象要实现了Serializeble接口(标记接口,不包括任何方法)。创建某些OutputStream对象,然后将其封装到一个ObjectOutputStream对象内。这时,调用writeObject()方法便可以将对向序列化,并将其发送给OutputStream(对象序列化是基于字节的)。反序列化:需要将一个InputStream封装到ObjectInputStream内,然后调用readObject(),获得的是一个指向Object的引用,需要向下转型设置成我们需要的对象。

对象序列化不仅保存了对象的“全景图”,而且还能追踪到对象内所包含的所有引用,并保存那些对象,接着又能对对象内包含的每个这样的引用进行追踪;依次类推。

public class Student implements Serializable { private static final long serialVersionUID = 1L;//自动添加的一个序列号 private String name; private Integer age; public Student() {} public Student(String n, Integer a){ name = n; age = a; } @Override public String toString(){ return "Student info [name=" + name + " , age=" + age + "]"; } public static void main(String[] args){ //--------------序列化 ObjectOutputStream oops = null; try{ //将对象写入文件 Student stu = new Student("sakura", 20); oops = new ObjectOutputStream(new FileOutputStream("E://test.txt")); oops.writeObject(stu); } catch(Exception e){ e.printStackTrace(); } finally{ if(oops != null){ try{ oops.close(); } catch(Exception e){ e.printStackTrace(); } } } //-----------反序列化 ObjectInputStream oips = null; try{ oips = new ObjectInputStream(new FileInputStream("E://test.txt")); //将Student对象的信息读取出来组装成一个Object对象,然后向下转型为Student对象 Student stu_back = (Student)oips.readObject();//向下转型 System.out.println(stu_back); } catch (Exception e) { e.printStackTrace(); } finally{ if(oips != null){ try{ oips.close(); } catch (Exception e) { e.printStackTrace(); } } } } } /* output: Student info [name=sakura , age=20] */

注意在对一个Serializable对象进行还原的过程中,没有调用任何构造器,包括默认的构造器。整个对象都是通过从InputStream中取得数据恢复而来的。

Java——IO系统概览

对象序列化的文件内容格式再此就不在详解。

transient(瞬时)关键字

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgdyfw.html