RandomAccessFile随机访问文件

package raf;

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

/**
 * java.io.RandomAccessFile
 * 随机访问文件
 * 是专门用来读写文件数据的类,其基于 指针 对文件进行随机访问,读写操作灵活。
 *
 * @author YanLy
 * @date 2021/5/26  15:41
 */
public class Test1_RAF {
    public static void main(String[] args) throws IOException {
        /*
        RandomAccessFile 常用的构造器
        RandomAccessFile(String path,String mode)
        RandomAccessFile(File file,String mode)
        第一个参数是要操作的文件,可以直接给路径,也可以指定一个File对象
        第二个参数是操作模式:r - 只读模式,rw - 读写模式。

        如果指定的文件不存在,会直接创建出来。
         */
        RandomAccessFile raf = new RandomAccessFile("./raf.txt","rw");
         /*
         void write(int d): 向文件中写入一个字节,写入的是int值对应的2进制的"低八位"
         0b00000000_00000000_00000000_00000001;
                                      "低八位"
         */
        raf.write('中');
        raf.write(1);
        raf.write(2);
        System.out.println("文件写出完毕!");
        // 关闭流  关了以后就不能用了 如果不关闭 会占用系统资源
        raf.close();
        // Scanner 也需要关闭流
        // Scanner名.close()
        //
        // 关闭之后可以打开,可以重新new创建


    }
}
package raf;

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

/**
 * @author YanLy
 * @date 2021/5/26  16:19
 */
public class Test2_RAF2 {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile("./raf.txt", "r");
       /*
            int read(): 读取一个字节并以int形式返回(读取的数据在int值对应的二进制的第八位上)
            如果返回的int值为 -1 则表示文件末尾
         */
        // read() 只能读取一个字节
        // 00000000_00000000_00000000_00000001
        int b = raf.read();
        System.out.println(b);
        // 00000000_00000000_00000000_00000010
        b = raf.read();
        System.out.println(b);
        b = raf.read();
        System.out.println(b);
        b = raf.read();
        System.out.println(b);
        b = raf.read();
        System.out.println(b);
        b = raf.read();
        System.out.println(b);
        b = raf.read();
        System.out.println(b);
        b = raf.read();
        System.out.println(b);
        b = raf.read();
        System.out.println(b);
        raf.close();
    }
}
package raf;

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


/**
 * 读写基本类型数据,以及RAF基于指针的读写操作
 *
 * @author YanLy
 * @date 2021/5/26  16:47
 */
public class Test3 {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
        long pos = raf.getFilePointer(); // 获取指针的位置
        System.out.println("pos: " + pos); // 0,默认从头开始  pos: 0
        /*
        max  =  0b01111111_11111111_11111111_11111111;  2147483647
        max >> 24
        max1 =  0b00000000_00000000_00000000_01111111;  127
        max >> 16
        max2 =  0b00000000_00000000_01111111_11111111;
        max >> 8
        max3 =  0b00000000_01111111_11111111_11111111;
         */
        int max = Integer.MAX_VALUE;

        raf.write(max>>24); // 127
        raf.write(max>>16); // 255
        raf.write(max>>8);  // 255
        raf.write(max); // 255
        System.out.println("pos: " + raf.getFilePointer()); // pos: 4

        raf.writeInt(max); // 连续写4个字节将int值写入文件,等同上面四句
        System.out.println("pos: " + raf.getFilePointer()); // pos: 8

        raf.writeLong(12345L);// 连续写8个字节将long值写入文件
        System.out.println("pos: " + raf.getFilePointer()); // pos: 16

        raf.writeDouble(3.1415926);// 连续写8个字节将double值写入文件
        System.out.println("pos: " + raf.getFilePointer()); // pos: 24

        // void seek() : 将指针移动到指定位置
        raf.seek(0); // 移动到文件最开始位置

        // 读取 int
        int a = raf.readInt();
        System.out.println(a); // 2147483647
        System.out.println("pos: " + raf.getFilePointer()); // pos: 4
        // 读取 long
        // 指针跳转 读取 long
        raf.seek(8);
        long b = raf.readLong();
        System.out.println(b); // 12345
        System.out.println("pos: " + raf.getFilePointer()); // pos: 16
        // 读取 double
        raf.seek(16);
        double c = raf.readDouble();
        System.out.println(c); // 3.1415926
        System.out.println("pos: " + raf.getFilePointer()); // pos: 24

        // 修改 long 的值为 56789
        raf.seek(8);
        raf.writeLong(56789L);
        System.out.println("pos: " + raf.getFilePointer()); // 16
        raf.seek(8);
        long e = raf.readLong();
        System.out.println(e); // 56789
        System.out.println("pos: " + raf.getFilePointer()); // 16

        raf.close();

    }
}

 

package raf;


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


/**
 * 文件的复制
 *
 * @author YanLy
 * @date 2021/5/28  11:44
 */
public class Test4_CopyDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile("./API.CHM", "r");
        RandomAccessFile desc = new RandomAccessFile("./API_copy.CHM", "rw");

        long start = System.currentTimeMillis(); // 开始毫秒
        int d;// 用于记录每次读取到的字节
        // (d = raf.read()) 写到外面不会参加循环了
        while ((d = raf.read()) != -1) {
            desc.write(d);
        }
        long end = System.currentTimeMillis(); // 结束毫秒
        System.out.println("复制完成,共耗时:" + (end - start) + "ms"); // 401216
        raf.close();
    }
}

 

package raf;

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

/**
 * 通过提高每次实际读写的数据量,减少实际读写的次数可以提高读写效率
 * 单字节读写属于随机读写模式,一组字节读写属于块读写。
 * 对于机械硬盘来说,随机读写的效率非常差,块读写效率还是不错的。
 *
 * @author YanLy
 * @date 2021/5/28  14:05
 */
public class Test5_CopyDemo2 {
    public static void main(String[] args) throws IOException {
        RandomAccessFile src = new RandomAccessFile("./API.CHM","r");
        RandomAccessFile desc = new RandomAccessFile("./API_copy.CHM","rw");
        /*
        int read(byte[] data) :
        一次性从文件中读取给定的字节组总长度的字节量,并存入到该数组中,
        返回值为实际读取到的字节量,如果返回-1则表示文件末尾。

        void write(byte[] data) : 一次性将给定的字节数组中的所有字节写入文件。
        void write(byte[] data,int offset,int len) :
        将给定的字节数组从下标为offset处的连续len个字节一次性写出


        当读取的数据小于数组的大小时,会有多余的默认值存在。
        所以在写出数据时,需要把多余的内容舍弃掉,
        write(byte[]data.int offset,int len)
        第一个参数是要写出的数组,
        第二个参数是指定从哪儿开始写出,
        第三个参数是写出的长度。

        8位 是 8bit
        00000000  1byte(1字节)
        1024 byte = 1 kb
        1024 kb = 1 mb
        1024 mb = 1 gb
        1024 gb = 1

         */
        // 数组的长度要求只能填写int
        byte [] data = new byte[1024*10]; // 10kb
        int len; // 记录每次实际读取到的字节数
        long start = System.currentTimeMillis(); // 开始毫秒

        while((len = src.read(data)) != -1){
            // 从原文件中实际读取到多少字节,就写多少字节
            /**
             * 为什么要把data写在参数里:
             * 答:从输入流中读取一定数量的字节,src.read(data),并将其存储在缓冲区数组 len 中。
              */

            desc.write(data,0,len);
        }
        long end = System.currentTimeMillis(); // 结束毫秒
        System.out.println("复制完成,共耗时:" + (end - start) + "ms"); // 401216

        src.close(); // 关闭流


    }
}
package raf;

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

/**
 * 向文件中写入字符串
 *
 * @author YanLy
 * @date 2021/5/28  15:27
 */
public class Test6_WriteStringDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
        /*
        GBK : 国际编码   英文占1个字节   中文占2个字节
        UTF-8 : 万国码   英文占1个字节   中文占 3个字节
         */
        String line = "就让秋风带走我的思念,带走我的泪~";
        /*
         byte[]  getBytes(): 将字符串按照指定字符集转换为字节数组
         getBytes() 方法是 String 类中的方法

         byte[] getBytes(String charsetName):
         将字符串按照指定字符集转换为字节数组,参数为编码集的名字

         如果编码集名字拼写有误  会抛出异常:
         UnsupportedEncodingException
         */

        byte [] data = line.getBytes("UTF-8");
        raf.write(data);
        System.out.println("写入完毕");

        raf.close();

    }
}

 

package raf;


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

/**
 * 从文件中读取字符串
 *
 * @author YanLy
 * @date 2021/5/28  15:24
 */
public class Test7_ReadStringDemo {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf = new RandomAccessFile("raf.txt","r");
        // 创建一个与文件等长的字节数组
        byte[]data = new byte[(int)raf.length()];
        // 一次性将文件中所有字节读入字节数组
        raf.read(data);
        // String类里的一个构造方法 参数为数组,还可以指定编码集
        // 将字节数组所有内容按照UTF-8字符集还原为字符串
        String str = new String(data,"UTF-8");
        System.out.println(str);

        raf.close();
    }
}
package raf;

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

import java.util.Scanner;

/**
 * 实现简易记事本
 * 程序启动后要求用户输入一个文件名,然后对该文件进行写操作,
 * 之后用户在控制台输入的每一行字符串都写入到该文件中(不考虑换行问题),
 * 当用户单独输入 "exit" 时程序退出
 *
 * @author YanLy
 * @date 2021/5/28  15:56
 */
public class Test8_Note {
    public static void main(String[] args) throws IOException {
        // 让用户输入文件名和文件内容
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入文件名:");
        String scan = scanner.nextLine();
        System.out.println("请输入文件内容:");

        // 向文件中写入字符串
        RandomAccessFile raf = new RandomAccessFile(scan+".txt","rw");

        while(true) {
            String info = scanner.next();
            // 把判断放前面再写
            // 已知内容的放在前面
            if("exit".equals(info)){
               break;
            }
            byte [] data1 = info.getBytes("UTF-8");
            raf.write(data1);
            System.out.println("保存成功!") ;
        }

        raf.close();
        System.out.println("再见,欢迎下次使用!");
    }
}
package raf;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Scanner;

/**
 *  完成用户注册功能:
 *  程序启动后,要求用户顺序输入:用户名,密码,昵称,年龄
 *  然后将该用户信息 写入文件user.txt
 *  设计格式:每条记录固定占用100字节
 *  其中用户名、密码、昵称各占32字节
 *  年龄固定4字节
 *  (对于字符串而言,故意留白的好处就是后期可以在添加字符,
 *  不会影响其他数据,而且长度固定,有利于指针的移动操作)
 *
 * @author YanLy
 * @date 2021/5/28  17:34
 */
public class Test9_RegDemo {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入名字:");
        String name = scanner.next();
        System.out.println("请输入密码:");
        String  password= scanner.next();
        System.out.println("请输入昵称:");
        String nickname = scanner.next();
        System.out.println("请输入年纪:");
        int age = scanner.nextInt();

        RandomAccessFile raf = new RandomAccessFile("user.txt","rw");
        // 把指针调到文件的长度
        raf.seek(raf.length());
        // 设置姓名
        byte [] data = name.getBytes("UTF-8");
        data = Arrays.copyOf(data,32);
        raf.write(data);
        // 设置密码
        data = password.getBytes("UTF-8");
        data = Arrays.copyOf(data,32);
        raf.write(data);
        // 设置昵称
        data = nickname.getBytes("UTF-8");
        data = Arrays.copyOf(data,32);
        raf.write(data);
        // 设置年龄

        raf.writeInt(age);

        System.out.println("写入完毕!");



        // 关闭流
        raf.close();
    }
}
package raf;

import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

/**
 * @author YanLy
 * @date 2021/5/29  9:27
 */
public class Test10_RegDemo1 {
    public static void main(String[] args) throws Exception {

        RandomAccessFile raf = new RandomAccessFile("user.txt","r");

        for (int i = 0; i < raf.length()/100; i++) {

            byte[]data = new byte[32];

            raf.read(data);
            String username = new String(data,"utf-8").trim();

            raf.read(data);
            String password = new String(data,"utf-8").trim();

            raf.read(data);
            String nickname = new String(data,"utf-8").trim();

            int age = raf.readInt();

            System.out.println(username + "," + password + "," + nickname + "," + age);
        }


        raf.close();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值