JAVA的I/O操作(四)

本文介绍Java中RandomAccessFile类的使用方法,包括文件的读写操作及文件指针的控制。同时,深入探讨对象序列化机制,演示如何序列化和反序列化对象,以及如何定制序列化过程。
 

JAVA的I/O操作(四)

RandomAccessFile

此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。 

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。

RandomAccessFile

public RandomAccessFile(File file, 

                        String mode) 

                 throws FileNotFoundException 

创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。将创建一个新的 FileDescriptor 对象来表示此文件的连接。 

mode 参数指定用以打开文件的访问模式。允许的值及其含意为: 

含意

"r"

以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。 

"rw"

打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。 

如果存在安全管理器,则使用 file 参数的路径名作为其参数调用它的 checkRead 方法,以查看是否允许对该文件进行读取访问。如果该模式允许写入,那么还使用该路径参数调用该安全管理器的 checkWrite 方法,以查看是否允许对该文件进行写入访问

----------------------------------------------------------------------------------------------

Serialize (色熬热熬赖此)

vt.

连载, 使连续

externalize

vt.

给...以外形, 使客观化, 使具体化

Transient

adj.

短暂的, 瞬时的

n.

瞬时现象

-------------------------------------------------------------------------------------------------

将某一对象转化为字节流保存起来并在日后对其进行恢复,这一行为称为“对象的序列化”,某一对象被序列化后保存的是该对象的非静态的成员变量,不会保存静态成员变量和任何方法,如果在该对象中存在不能序列化的某类对象的引用,则必须将该引用用关键字transient标识,才能将对象序列化。

--------------------------------------------------------------------------------------------------

public interface Serializable 

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

要允许不可序列化类的子类型序列化,可以假定该子类型负责保存和恢复超类型的公用 (public)、受保护的 (protected) 和(如果可访问)包 (package) 字段的状态。仅在子类型扩展的类有一个可访问的无参数构造方法来初始化该类的状态时,才可以假定子类型有此职责。如果不是这种情况,则声明一个类为可序列化类是错误的。该错误将在运行时检测到。 

在反序列化过程中,将使用该类的公用或受保护的无参数构造方法初始化不可序列化类的字段。可序列化的子类必须能够访问无参数构造方法。可序列化子类的字段将从该流中恢复。 

当遍历一个图形时,可能会遇到不支持 Serializable 接口的对象。在此情况下,将抛出 NotSerializableException,并将标识不可序列化对象的类。 

在序列化和反序列化过程中需要特殊处理的类必须使用下列准确签名来实现特殊方法: 

 private void writeObject(java.io.ObjectOutputStream out) 

     throws IOException 

 private void readObject(java.io.ObjectInputStream in) 

     throws IOException, ClassNotFoundException; 

 private void readObjectNoData()  

     throws ObjectStreamException; 

 

writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法可以恢复它。通过调用 out.defaultWriteObject 可以调用保存 Object 的字段的默认机制。该方法本身不需要涉及属于其超类或子类的状态。通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream,状态可以被保存。 

readObject 方法负责从流中读取并恢复类字段。它可以调用 in.defaultReadObject 来调用默认机制,以恢复对象的非静态和非瞬态字段。defaultReadObject 方法使用流中的信息来分配流中通过当前对象中相应指定字段保存的对象的字段。这用于处理类演化后需要添加新字段的情形。该方法本身不需要涉及属于其超类或子类的状态。通过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream,状态可以被保存。 

1.文件随机读写

import java.io.*;

public class RandomAccessFileIO 

{

 public static void main(String[] args) throws Exception

 {

  RandomAccessFile rdaf=new RandomAccessFile("access.txt","rw");

  System.out.println(rdaf.length()+"/n"+rdaf.getFilePointer());

  rdaf.writeUTF("hello,world");

  System.out.println(rdaf.length()+"/n"+rdaf.getFilePointer());

  rdaf.seek(0);

  System.out.println(rdaf.length()+"/n"+rdaf.getFilePointer());

  System.out.println(rdaf.readUTF());

  System.out.println(rdaf.length()+"/n"+rdaf.getFilePointer());

 }

}

2.对象序列化:

import java.io.*;

public class SerializableTest 

{

    public static void main(String[] args) throws Exception

    {

     FileOutputStream fops=new FileOutputStream("random.txt");

     ObjectOutputStream oops=new ObjectOutputStream(fops);

        Event e1=new Event(1,"some one buy me a book");

        Event e2=new Event(2,"they say I am smart");

        Event e3=new Event(3,"I lost 1 yuan");

        oops.writeObject(e1);

        oops.writeObject(e2);

        oops.writeObject(e3);

        oops.close();

        FileInputStream fips=new FileInputStream("random.txt");

        ObjectInputStream oips=new ObjectInputStream(fips);

        for(int i=0;i<3;i++)

        {

         Event e=new Event();

         e=(Event)oips.readObject();

         System.out.println(e.number+" "+e.summary);

        }

        oips.close();

 }

}

class Event implements Serializable

{

 public int number;

 public String summary;

 Event()

 {

 }

 Event(int number,String summary)

 {

  this.number=number;

  this.summary=summary;

 }

 private void writeObject(java.io.ObjectOutputStream o1) throws IOException

 {

  o1.writeInt(number);

  o1.writeUTF(summary);

  o1.writeUTF("-------分隔符---------");

 }

    private void readObject(java.io.ObjectInputStream i1) throws IOException

    {

     number=i1.readInt();

     summary=i1.readUTF();

     System.out.println("/n"+i1.readUTF());

    }

}

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值