美文网首页
JavaSE常用API之RandomAccessFile

JavaSE常用API之RandomAccessFile

作者: WEtcmind | 来源:发表于2019-04-06 18:54 被阅读0次

    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

          本文链接:https://www.haomeiwen.com/subject/fpzriqtx.html