JavaSE常用API之RandomAccessFile

RandomAccessFile是Java中输入/输出流体系中功能最丰富的文件内容访问类,它提供很多方法来操作文件,包括读写支持,与普通的IO流相比,它最大的特别之处就是支持任意访问的方式,程序可以直接跳到任意地方来读写数据(根据指针来实现)。

RandomAccessFile的超类是Object,而其他输入/输出流的超类是Stream(InputStream/OutputStream);

java.io.RandomAccessFile


  1. 创建RandomAccessFile实例

    别忘了导包!以后就不会专门说明了!!!

代码示例:

    
    /* 
     * RandomAccessFile raf = new RandomAccessFile(String name,String mode)
     * @param name : 要操作的文件名,若是不存在则创建新的文件
     * @param mode : r  --只读模式  调用文件的任何 write 方法都将导致抛出 IOException
     *               wr --读写模式 (这两种模式常用)
     */
    public class RandomAccessFileDemo {
    public static void main(String[] args) throws IOException { //io操作会有异常产生,在本阶段异常暂不做介绍,以后详解
        System.out.println("程序开始!");
        /*
         * RAF的常用构造方法:
         * RandomAccessFile(String path,String mode)
         * RandomAccessFile(File file,String mode)
         * 
         * 第二个参数为模式,常用的为"r","rw"
         * 需要注意,若指定文件不存在,那么若模式为"rw"时,RAF会自
         * 动创建该文件,但如果模式为"r",则会抛出
         * FileNotFoundException(继承了IOException)异常
         * 也可以创建一个文件(File file)
         * 
         * 在真实的项目环境下,为了兼容多种设备环境,若是文件使用绝对路径(文件的准确位置)
         * 那么只能在同种平台使用比如:
         * D:\demo\demo.txt 在Linux中没有D:这个概念
         * 所以为了跨平台(一次编写到处运行)文件的路径一般为相对路径 
         *  ./代表当前目录(不写也可)
         * ../回退到上层目录
         * ./dir1/dir2/test.txt 代表 当前dir1目录下的dir2目录中的test.txt 比如:src/image/girl.png
         * 
         */
        RandomAccessFile raf = 
                new RandomAccessFile("./raf.dat", "r"); 
        System.out.println("程序结束!");
        raf.close();
        
        
    }

}
  1. 常用API

    • void write(int b) 向文件中写入指定字节 默认向文件中写入1个字节 写入的是给定的int值所对应的2进制“低8位”
    • void write(byte[] b) 向文件中写入指定的块字节(字节数组)
    • void read() 从此文件中读取一个字节
    • void read(byte[] b) 从此文件中按块字节(字节数组),读取文件
    • String 提供了讲字符串转换为字节的方法 getBytes() 返回的是个字节数组
    • 重载的getBytes(Charset charset) 转换为指定字符集的字节数组
    • void close() 关闭RandomAccessFile流

    int是4个字节,32位的2进制数。int 0 ==> 2进制表示:"00000000(高8位) 00000000 00000000 00000000(低8位)"
    int低8位的最大值为255:"00000000 00000000 00000000 11111111",超过范围自动进位溢出!!!

    • long getFilePointer() 获取指针位置 native修饰的本地方法
    • void seek() 移动文件指针位置
    • 读写 8大基本类型 write/read+基本数据类型修饰首字母大写 如:
    • 写:
    • writeDouble() 写双精度浮点数
    • writeInt() 写整数
    • writeLong() 写长整型
    • ...
    • 读:
    • readInt() 读取int

代码示例:

    
    /**
     * 向文件中写入数据
     * void write()
     * 向文件中写入1个字节 写入的是给定的int值所对应的2进制“低8位”
     * int 4个字节 每个字节是8位 共32位   最多写入255个字节 "11111111"
     * void close() 关闭RandomAccessFile流
     * 进行io操作 要及时关闭 防止增加内存负担 ,造成效率消耗
     *
     */
    public class WriteDemo {

        public static void main(String[] args) throws IOException {
            //创建实例
            RandomAccessFile raf = 
                    new RandomAccessFile("./raf.dat", "rw");
            //只写二进制的低8位 高位移除 一次性写入200个字节,
            raf.write(200); 
            //打桩测试
            System.out.println("写入成功");
            //关闭流 及时释放资源
            raf.close();
            
        }

    }
    /**
     * void write(byte[] data)
     * 一次性将给定的字节数组中所有字节写入文件
     */
    public class WriteStringDemo {

    public static void main(String[] args) throws IOException {
        //实例
        RandomAccessFile raf = 
                new RandomAccessFile("raf.txt", "rw");
        String str = "hello,world";
        //将要写入的字符串转换为字节(数组形式)
        byte[] data = str.getBytes("utf-8");
        /**
         * String 提供了转换为字节的方法
         * byte[] getBytes()    
         * 将当前字符串按照系统默认字符集转换为一组字节
         */
        //写入文件
        raf.write(data);
        raf.write("Welcome To China".getBytes("utf-8"));
        System.out.println("写出完毕");
        raf.close();
        }
        
    }

读写基本数据类型以及基于文件指针的读写操作:

    package raf;

    import java.io.IOException;
    import java.io.RandomAccessFile;

    /**
     * RandomAccessFile读写基本类型数据以及基于指针读写的操作
     * long getFilePointer() 获取指针位置  native修饰的本地方法
     * native关键字说明其修饰的方法是一个原生态方法,
     * 方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。 (在此只做了解)  
     * 
     * void seek() 移动文件指针位置
     * 文件在写入完毕之后,指针会在文件的末尾,要想读取数据要将指针移动到文件的开头
     * 
     * 读写 8大基本类型  write/read+基本数据类型修饰[首字母大写]() 如:
     * 写:
     *  writeDouble() 写双精度浮点数
     *  writeInt() 写整数
     *  writeLong() 写长整型
     *  ...
     * 读:
     *  readInt() 读取int  
     *  ...
     * 
     */
    public class RandomAccessFileDemo02 {

        public static void main(String[] args)
                throws IOException {
            RandomAccessFile raf = 
                    new RandomAccessFile("raf.txt", "rw");
            System.out.println("pointer:"+raf.getFilePointer());
            int max = Integer.MAX_VALUE;
            raf.write(max>>24);
            System.out.println("pointer:"+raf.getFilePointer());
            raf.write(max>>16);
            raf.write(max>>8);
            raf.write(max);
            System.out.println("pointer:"+raf.getFilePointer());
            
            raf.writeInt(max);
            System.out.println("pointer:"+raf.getFilePointer());
            
            raf.writeDouble(123.123);
            System.out.println("pointer:"+raf.getFilePointer());
            
            raf.writeLong(100L);
            System.out.println("pointer:"+raf.getFilePointer());
            
            System.out.println("写出完毕");
            
            //指针移回开始 0 
            raf.seek(0);
            //读取  文件中 int 数据
            int i = raf.readInt();
            System.out.println(i);
            System.out.println("pointer:"+raf.getFilePointer());
            
            //读取 文件中long 值
            raf.seek(16);
            long l = raf.readLong();
            System.out.println(l);
            System.out.println("pointer:"+raf.getFilePointer());
            
            //重写 文件中 double 值
            raf.seek(8);
            raf.writeDouble(456.456);
            //读取 文件中 double 值
            raf.seek(8);
            double d = raf.readDouble();
            System.out.println(d);
            System.out.println("pointer:"+raf.getFilePointer());
            //关闭IO
            raf.close();
        }

    }

小案例1_复制文件:

    /**
     * int read(byte[] date)
     * 一次性从文件中读取给定的字节数组总长度的字节量
     * 并将读取到的字节顺序存入到该数组中
     * 返回值为实际读取到的字节量,若返回值为-1,则表
     * 示读取到了文件末尾(每次也没有读取到任何自己)
     *  
     * void write(byte[] data,int offset,int len) 
     * 将给定的字节数组 从下标offset处开始  连续len个字节一次性
     * 写入到文件中
     *
     */
    public class CopyDemo2 {

        public static void main(String[] args) throws IOException {
            /* 源文件 */
            RandomAccessFile src = 
                    new RandomAccessFile("src/demo.txt", "r");
            /* 目标文件  */
            RandomAccessFile desc = 
                    new RandomAccessFile("demo_cpoy.txt", "rw");
            /* 用于记录每次实际读取到的字节数 */
            int len = -1;
            /* 保存每次读取到的字节 10k */
            byte[] data = new byte[1024*10];
            
            long start = System.currentTimeMillis();
            /* 块读取源文件 当读取的不是文件末尾时循环读取 */
            while((len = src.read(data))!=-1){
                /* 块写入目标文件 */
                desc.write(data,0,len);
            }
            long end = System.currentTimeMillis();
            System.out.println("复制完毕!耗时"+(end-start)+"ms");
            src.close();
            desc.close();
            
        }

    }

小案例2_记事本:

    /**
     * 简易的记事本工具
     * 需求: 
     *      1.向指定的文件写入内容(用户操作) 
     *      2. 在用户输入"exit"(单行)时退出
     */
    public class Notepad {

        public static void main(String[] args) throws IOException {
            writeAgain();
        }

        public static void writeAgain() throws IOException{
            //创建接收器
            Scanner scan = new Scanner(System.in);
            System.out.println("请输入要操作的文件名:");
            //接收用户需要操作的文件名
            String fileName = scan.nextLine();
            //文件实例
            RandomAccessFile raf =
                    new RandomAccessFile(fileName, "rw");
            System.out.println("请开始输入内容:");
            while(true){
                //接收用户输入的内容
                String line = scan.nextLine();
                //输入exit退出
                if("exit".equals(line)){
                    break;
                }
                //向文件中写入内容
                raf.write(line.getBytes("utf-8")); //指定编码写入
            }
            System.out.println("再见");
            raf.close();
            scan.close();
        }
    }

你可能感兴趣的:(JavaSE常用API之RandomAccessFile)