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();
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容