java IO之 RandomAccessFile类

RandomAccessFile类可以说是Java语言中功能最为丰富的文件访问类,它提供了众多的文件访问方法。RandomAccessFile类支持随机访问方式,可以跳转到文件的任意位置处读写数据。在要访问一个文件的时候,不想把文件从头读到尾,而是希望像访问一个数据库一样地访问一个文本文件,这时使用RandomAccessFile类就是最佳选择。

RandomAccessFile对象类有个位置指示器,指向当前读写处的位置,当读写n个字节后,文件指示器将指向这n个字节后的下一个字节处。刚打开文件时,文件指示器指向文件的开头处,可以移动文件指示器到新的位置,随后的读写操作将从新的位置开始。

RandomAccessFile类是一个特殊IO流,它不能访问除File以外的其他的任何IO设备,只是对File进行操作。这个类的特点是随机访问File类的任何一个位置开始读取。其RandomAccessFile类内部有一个类似与指针的指示器,控制这它访问开始的位置或者当前访问的位置。很多的断点下载都是通过他的原理来实现的。

   RandomAccessFile类的常用实现就是读取一个等长的数据,因为每一条数据都是等长的,我们可以直接在第2条数据或者第200条数据开始读取。就像我们java的加密一样,我们双方都知道一个特定的格式了,所以你加密后的文件在我的系统中能够被读取。等长数据就是字符长度一定的数据。下面我用一个例子来具体解释这个类一些基本方法和实现。

public class Employee {  
    private String name;  
    private int age;  
    public static final int len = 12;  
    /* 
     * 创建这个类的目的在于,创建一个等长的数据。 
     */  
    public Employee() {  
    }  
    public Employee(String name, int age) {  
        this.setName(name);  
        this.setAge(age);  
    }  
    public String getName() {  
        return name;  
    }  
    /** 
     * 这个里面就是控制name属性字符长度不会超出8个字符长度。 
     * @param name 
     */  
    public void setName(String name) {  
        StringBuilder builder = null;  
        if (null != name && (len - 4) <= name.length()) {  
            builder = new StringBuilder(name);  
        } else if (null == name) {  
            builder = new StringBuilder(len - 4);  
        } else {  
            builder = new StringBuilder(name);  
            while (builder.length() < (len - 4)) {  
                builder.append("/u0000");  
            }  
        }  
        builder.setLength(len - 4);  
        this.name = builder.toString();  
    }  
    public int getAge() {  
        return age;  
    }  
    public void setAge(int age) {  
        this.age = age;  
    }  
}  
 

准备工作我们做好以后,我们开始写一个我们测试用的类如下:

import java.io.FileNotFoundException;  
import java.io.RandomAccessFile;  
  
public class EmplyoeeTest {  
    /** 
     * @param args 
     * @throws FileNotFoundException  
     */  
    public static void main(String[] args) throws Exception {  
        /** 
         * 创建3条等长数据 
         */  
        Employee e1=new Employee("田智文",12);  
        Employee e2=new Employee("abcdefghijklmnopqrstuvwsyz",23);  
        Employee e3=new Employee("wangwu",66);  
        /** 
         * 打开一个文件,如果没有这个文件他会为我们创建这个文件,rw是一读写的方式打开的,这里区分以只读的方式打开 
         * 为什么使用writeChars方法,是因为我们java里面一个汉字和一个英文都是一样的长度,字节数也是一样的,但是 
         * 在系统中一个汉字的字节数为2个字节,而英文的字节数为1个字节。我们使用这个方法,就是让一个英文的字节数也 
         * 占2个字节。 
         */  
        RandomAccessFile accessFile=new RandomAccessFile("employee.txt","rw");  
        accessFile.writeChars(e1.getName());  
        accessFile.writeInt(e1.getAge());  
        accessFile.writeChars(e2.getName());  
        accessFile.writeInt(e2.getAge());  
        accessFile.writeChars(e3.getName());  
        accessFile.writeInt(e3.getAge());  
        accessFile.close();  
          
      
        RandomAccessFile read=new RandomAccessFile("employee.txt","r");//自读的方式打开文件  
        read.seek((Employee.len-4) *  2 + 4);//这个方法是RandomAccessFile类里面的指针的一定,这个方法绝对移动到一个位置。  
        //Employee.len-4) *  2 + 4,是因为我写入的时候把一个英文字节写如2个字节的位置,所以长度自然要加一倍,下面也是同理  
        StringBuilder builder=new StringBuilder(); //String是固定不变的,在进行字符串连接的时候是新建一个字符串,进行连接后,最后赋值,如果对String赋值多次,就会在内存中保存多个这个对象的副本,浪费系统资源;StringBuilder是可变的,不用生成中间对象,拼接字符串比较多,或字符串的长度比较长时有较高的效率。StringBuilder的内存空间不够也要扩容,如果分配的空间远远大于需要量,也很浪费所以,初始化StringBuilder的时候最好根据需要设置容量,避免浪费。
        for (int i = 0; i < (Employee.len-4); i++) {  
            builder.append(read.readChar());  
        }  
        System.out.println("第二名员工的名字:"+builder.toString().trim()+"---年龄:"+read.readInt());  //trim()从此实例的开始位置和末尾移除空白字符的所有匹配项。
        read.skipBytes((Employee.len-4) * 2);//这个方法是相对当前指针位置的移动  
        System.out.println("第三名员工的年龄:"+read.readInt());  
        read.seek(0);  
        StringBuilder builder1=new StringBuilder();  
        for (int i = 0; i < (Employee.len-4); i++) {  
            builder1.append(read.readChar());  
        }  
        System.out.println("第一名员工的名字:"+builder1.toString().trim()+builder1.toString().getBytes().length+"---年龄:"+read.readInt());  
        read.close();     
    }  
}  
 
转载 http://blog.csdn.net/tianzhw/article/details/6117005

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值