zoukankan      html  css  js  c++  java
  • javaIO:RandomAccessFile

    RandomAccessFile

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

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

    RandomAccessFile类在文件随机(相对于顺序)读取时有很大的优势,但该类仅限于操作文件,不能访问其他得IO设备,如网络、内存映像等。

     

    RandomAccessFile构造方法

    RandomAccessFile类为用户提供了两种构造方法:

    1、RandomAccessFile(File file, String mode)

    2、RandomAccessFile(String name, String mode)

    其实第二种构造方法也是new一个File出来再调用第一种构造方法,建议使用第一种构造方法,因为第一篇文章就说了File是IO的基础,有一个File不仅仅可以通过RandomAccessFile对文件进行操作,也可以通过File对象对文件进行操作。至于mode,Java给开发者提供了四种mode:

    模    式作    用
    r表示以只读方式打开,调用结果对象的任何write方法都将导致抛出IOException
    rw打开以便读取和写入,如果该文件尚不存在,则尝试创建该文件
    rws打开以便读取和写入,相对于"rw",还要求对文件内容或元数据的每个更新都同步写入到底层存储设备
    rwd打开以便读取和写入,相对于"rw",还要求对文件内容的每个更新都同步写入到底层存储设备

    注意第二点"rw"模式,对rw模式的解释意味着Java并不强求指定的路径下一定存在某个文件,假如文件不存在,会自动创建

     

    RandomAccessFile中的方法

    RandomAccessFile中有如下一些常用方法:

    方    法作    用
    void close()重要,关闭此随机访问文件流并释放与该流关联的所有系统资源
    FileChannel getChannel()返回与此文件关联的唯一FileChannel对象,NIO用到
    long getFilePointer()返回此文件中的当前偏移量
    long length()返回此文件的长度
    int read()从此文件中读取一个数据字节
    int read(byte[] b)将最多b.length个数据字节从此文件读入byte数组,返回读入的总字节数,如果由于已经达到文件末尾而不再有数据,则返回-1。在至少一个输入字节可用前,此方法一直阻塞
    int read(byte[] b, int off, int len)将最多len个数据字节从此文件的指定初始偏移量off读入byte数组
    boolean readBoolean()从此文件读取一个boolean,其余readByte()、readChar()、readDouble()等类似
    String readLine()从此文件读取文本的下一行
    void seek(long pos)重要,设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作
    int skipBytes(int n)重要,尝试跳过输入的n个字节以丢弃跳过的字节,返回跳过的字节数  

    以上标注红点的是重要的区别点
    void write(byte[] b)将b.length个字节从指定byte数组写入到此文件中
    void write(byte[] b, int off, int len)将len个字节从指定byte数组写入到此文件,并从偏移量off处开始
    void write(int b)向此文件写入指定的字节
    void writeBoolean(boolean v)按单字节值将boolean写入该文件,其余writeByte(int v)、writeBytes(String s)、writeChar(int v)等都类似

     

    RandomAccessFile使用实例

    先定义一个实体类:

    public class Employee
    {
        private String                name;
        private int                   age;
        private final static int      LEN = 8;
        
        public Employee()
        {
            
        }
        
        public Employee(String name, int age)
        {
            if (name.length() > LEN)
            {
                name = name.substring(0, 8);
            }
            else
            {
                while (name.length() < LEN)
                {
                    name = name + "u0000";
                }
            }
            this.name = name;
            this.age = age;
        }
        
        public String getName()
        {
            return name;
        }
        
        public void setName(String name)
        {
            this.name = name;
        }
        
        public int getAge()
        {
            return age;
        }
        
        public void setAge(int age)
        {
            this.age = age;
        }
    }

    第一部分,写文件,该文件在路径下并没有,所以Java会自动帮我们创建:

    Employee e1 = new Employee("zhangsan", 23);
    Employee e2 = new Employee("lisi", 24);
    Employee e3 = new Employee("wangwu", 25);
            
    RandomAccessFile raf0 = new RandomAccessFile("D:/employee.txt", "rw");
    raf0.writeBytes(e1.getName());
    raf0.writeInt(e1.getAge());
    raf0.writeBytes(e2.getName());
    raf0.writeInt(e2.getAge());
    raf0.writeBytes(e3.getName());
    raf0.writeInt(e3.getAge());
    raf0.close();

    文件创建好了,D盘下也有该文件了,所以读取一下,这里使用了一些小技巧来演示seek方法和skipBytes方法:

    RandomAccessFile raf1 = new RandomAccessFile("D:/employee.txt", "r");
    int len = 8;
    raf1.skipBytes(12); // 跳过第一个员工的信息,其姓名8字节,年龄4字节
    System.out.println("第二个员工的信息:");
    String str = "";
    for (int i = 0; i < len; i++)
    {
        str = str + (char)raf1.readByte();
    }
    System.out.println("name:" + str);
    System.out.println("age:" + raf1.readInt());
    System.out.println("第一个员工的信息:");
    raf1.seek(0);
    str = "";
    for (int i = 0; i < len; i++)
    {
        str = str + (char)raf1.readByte();
    }
    System.out.println("name:" + str);
    System.out.println("age:" + raf1.readInt());
    System.out.println("第三个员工的信息:");
    raf1.skipBytes(12); // 跳过第二个员工的信息
    str = "";
    for (int i = 0; i < len; i++)
    {
        str = str + (char)raf1.readByte();
    }
    System.out.println("name:" + str.trim());
    System.out.println("age:" + raf1.readInt());
    raf1.close();

    看一下运行结果:

    第二个员工的信息:
    name:lisi
    age:24
    第一个员工信息:
    name:zhangsan
    age:23
    第三个员工信息:
    name:wangwu
    age:25

    可能有人奇怪,"zhangsan"加上一个int跳过12个字节可以理解,但是"lisi"、"wangwu"为什么加上int要跳过12个字节呢?明明"lisi"只有4个字节,"wangwu"只有6个字节啊。这个就涉及到一个"字节对齐"的问题了,有兴趣的可以了解一下。另外,再说一下,RandomAccessFile使用完一定要及时close()。

     

  • 相关阅读:
    jQuery 基本选择器
    JavaScriptif while for switch流程控制 JS函数 内置对象
    JavaScrip基本语法
    数据库 存储引擎 表的操作 数值类型 时间类型 字符串类型 枚举集合 约束
    数据库基础知识 管理员 用户登录授权的操作
    粘包的产生原理 以及如何解决粘包问题
    socket TCP DPT 网络编程
    2018年年终总结
    Android技术分享
    No accelerator found
  • 原文地址:https://www.cnblogs.com/signheart/p/14442604.html
Copyright © 2011-2022 走看看