Num11_RandomAccessFile随机读写文件流

RandomAccessFile随机存取文件流

java.io.RandomAccessFile 随机存取文件流
是专门用来读写文件数据的类,其基于指针对文件进行随机访问
读写操作灵活。

构造方法

使用一个已经存在的文件来创建一个RandomAccessFile对象。

  • RandomAccessFile(File file, String mode)
    创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定

使用一个字符串路径来创建一个RandomAccessFile对象。指定访问模式

  • RandomAccessFile(String name, String mode)
    创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。

常用方法

  • void write(int b);虽然参数是int型,但是写入时并不能完整的将int型数据写入文件,只能想文件中写入1个字节,写入的是给定的int值对应的二进制的“低八位”

  • void write(byte[] b)
    一次性将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始,实现块写入

  • void write(byte[] b, int off, int len)
    将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。(将给定的字节数组从下标offset处连续len个字节一次性写出)

  • void write(byte[] data ,int offset,int raf.read(data))//从指定位置写入实际的字节数

  • writeInt(int v)连续写入4字节将int 值写入文件中

  • writeLong(long v); 连续写入8字节。将long 值写入文件

  • raf.writeDouble(double v);连续写入8字节,将double值写入文件

  • void close()
    关闭此随机访问文件流并释放与该流关联的所有系统资源。

    当流关闭之后不能再继续写出 ,否则会抛出IO异常: java.io.IOException:Stream Closed
    raf.write(100);

  • long getFilePointer()
    返回此文件中的当前偏移量。getFilePointer()是获取写入字节数。

  • int read();
    读取一个字节并以int形式返回(读取的数据在 int 值对应的二进制的低八位上)如果返回的int值为-1则表示读到了文件末尾

  • int read(byte[] b)
    一次性从文件中读取给定的字节数组总长度(b.length)的字节量,并存入到该数组中,
    返回值为实际读取到的字节量,如果返回值-1则表示文件末尾

  • int read(byte[] b, int off, int len)
    将最多 len 个数据字节从此文件读入 byte 数组0

  • int readInt()
    从此文件读取一个有符号的 32 位整数。

  • String readLine()
    从此文件读取文本的下一行

  • void seek(long pos)
    设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作

  • String类提供了一个构造方法:
    String(byte bytes[], String charsetName)
    将指定的字节数组中的数据按照指定的字符集转换为字符串

将byte数组转换为String,指定编码集byte的默认值空格转换为String时 会转成空白,可以直接调用trim()去掉两边的空白

String username = new String(data,"UTF-8").trim();

RandomAccessFile 常用构造器:

RandomAccessFile(String path,String mode);
RandomAccessFile(File file,String mode);
第一个参数是要**操作的文件,可以直接给路径,或指定一个File对象
第二个参数是操作模式:r -只读模式,rw - 读写模式
** 创建RandomAccessFile对象时,若指定的文件不存在,则根据操作模式不同,结果不同。
如果操作模式是 r (只读模式),则会抛出文件找不到异常:FileNotFoundException
如果是rw(读写模式) ,如果指定文件不存在则会直接将文件创建出来。

data.getByte(charSetName); 将要写出的文件内容从磁盘到看得见的地方,用起来也方便。

题:1.获取当前目录下所有文件及文件夹,

2.列出当前目录下所有的文件及文件夹项。

public class Test1HW {
    public static void main(String[] args) throws IOException {
        File dir = new File(".");
        //2.列出当前目录下所有的文件及文件夹项。使用lambda表达式过滤出符合要求的文件
        File[] files = dir.listFiles(file -> file.isFile());
        RandomAccessFile src = null;
        RandomAccessFile desc = null;
        //3.循环遍历获取到的所有文件进行赋值
        for (int i = 0; i < files.length;i++){
            //4.获取每个子项的名字
            String fileName = files[i].getName();
            //5.获取最后一个.的下标
            int index = fileName.lastIndexOf(".");
            //6.获取后缀名之前的名
            String name = fileName.substring(0,index);
            //7.获取后缀名
            String ext = fileName.substring(index);
            StringBuilder copyFileName = new StringBuilder(fileName);
            copyFileName.insert(index,"_cp");
            //开始复制
            src = new RandomAccessFile(fileName,"r");
            //StringBuilder转String直接加空串或使用String.valueOf()
            desc = new RandomAccessFile(copyFileName+"","rw");
        }
        //关流
        src.close();
        desc.close();
    }
}

使用RandomAccessFile实现用户注册

package JAVA_API.num11_RandomAccessFile;

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 yyc
 * 2021/9/14 14:03
 */
public class Test6_Regist {
    public static void main(String[] args) throws IOException {
        Scanner scan = new Scanner(System.in);
        System.out.println("欢迎注册!");
        System.out.println("请输入用户名:");
        String username = scan.nextLine();
        System.out.println("请输入密码:");
        String password = scan.nextLine();
        System.out.println("请输入昵称:");
        String nickname = scan.nextLine();
        System.out.println("请输入年龄:");
        int age = scan.nextInt();

        //将控制台输入的信息写出到.txt文件
        RandomAccessFile raf = new RandomAccessFile("user.txt","rw");
        /*
         * 为了避免后面注册的用户信息覆盖之前用户的信息。在写入之前先将指针移动到文件末尾
         * */
        raf.seek(raf.length());
        //开始写数据
        /*
         * byte[] getBytes(),将字符串按照系统默认的编码集转换为byte[]数组.(编码集和字符集一个意思)
         * byte[] getBytes(String charsetName),将字符串按照指定的字符集转化为byte[]数组
         * */
        //写入用户名:
        //getBytes()使用默认的编码,想要指定编码格式,使用重载方法getBytes(String charsetName)
        byte[] data = username.getBytes("UTF-8");
        //System.out.println(Arrays.toString(data));//byte[] data = username.getBytes(),[115, 97, 116, 106]
        //将数组扩容至32字节,浅层复制,更换引用的指向
        data = Arrays.copyOf(data,32);
        raf.write(data);//写入32字节
        //写入密码,先将密码转成byte数组,
        data = password.getBytes("UTF-8");
        data = Arrays.copyOf(data,32);
        raf.write(data);
        //写入昵称
        data= password.getBytes("UTF-8");
        data = Arrays.copyOf(data,32);
        raf.write(data);
        System.out.println("注册完毕!");
        //写入年龄
        raf.writeInt(age);//writeInt(int a)//固定写入4字节
        //关流
        raf.close();
    }
}

/*完成修改昵称的功能:
 *程序启动后,要求用户输入用户名和新昵称
 * 然后修改user.txt文件中的该用户的昵称
 * 如果输入的用户不存在,则输出”查无此人“
 * */
 public class Test2_HW {
    public static void main(String[] args) throws IOException {
        //请输入用户名
        String name = new Scanner(System.in).nextLine();
        RandomAccessFile raf = new RandomAccessFile("user.txt","r");
        boolean flag = false;
        for (int i = 0; i < raf.length();i++){
            //先挪指针的位置
            raf.seek(i*100);
            //指定读入(从文件读到程序)的字节长度
            byte[] data = new byte[32];
            raf.read(data);
//将字节数组转换为字符串直接使用构造方法String(byte[] b, String charSetName);
            String username = new String(data,"UTF-8");

            if (username.equals(name)){
                //请输入新昵称
                String nick = new Scanner(System.in).nextLine();
                //将字符串转变为字节数组,指定字符集
                data = nick.getBytes("UTF-8");
                data = Arrays.copyOf(data,32);
//设置开始写入的位置,因为指针位置是64字节开始是昵称
                raf.seek(i*100+64);
                raf.write(data);
                flag = true;
                break;
            }
        }`

使用RandomAccessFile 实现文件复制


//将user.txt文件中的所有用户读取出来并输出到控制台

public class Test4_CopyDemo {
    public static void main(String[] args) throws IOException {
        //路径可以用字符串保存。
        String src = "E:\\web学习\\华创\\JHC2108\\API讲义\\API讲义.md";
        RandomAccessFile rafsrc = new RandomAccessFile(src,"r") ;
        //目标文件(必须是文件,不能是文件夹而且是新文件(如果不是一个新文件会怎么样:java.io.FileNotFoundException))
        String desc = "E:\\web学习\\华创\\JHC2108\\面向对象讲义\\面向对象讲义copy.md";
        RandomAccessFile rafdesc = new RandomAccessFile(desc,"rw");
        int d = 0;//用来记录每次读取的字节。即每次read()的返回值
        //当读取源文件中的内容不等于 -1 时,表示一直读
        long start = System.currentTimeMillis();//记录开始时间
        while((d = rafsrc.read())!= -1){//没有读取到文件末尾就一直读
            rafdesc.write(d);//将读到的字节数写入目标文件中
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕,耗时:" + (end - start));
        rafsrc.close();
        rafdesc.close();
    }
}

使用RandomAccessFile读取文件内容

public class Test7_ShowAllUserDemo {
    public static void main(String[] args) throws IOException {
        //要从这个文件中读取数据,必须要有一个RandomAccessFile 对象
        RandomAccessFile raf= new RandomAccessFile("user.txt","r");
        /*
        * 每个用户占100字节,所以 raf.length() / 100是用户个数
        * */
        for (int i = 0; i < raf.length() / 100; i++){
            //读取用户名
            byte[] data = new byte[32];
            raf.read(data);//只需要把读到的信息放入到data数组中
           /*
           * String类提供了一个构造方法:
           * String(byte bytes[], String charsetName)
           * 将指定的字节数组中的数据按照指定的字符集转换为字符串
           * */
            //将byte数组转换为String,指定编码集,byte的默认值空格转换为String 会转成空白,可以直接调用trim()去掉两边的空白
            String username = new String(data,"UTF-8").trim();

            //读取密码,指针位置是接着上一次读取的位置
            data = new byte[32];
            raf.read(data);
            String password = new String(data,"UTF-8").trim();

            //读取昵称
            data = new byte[32];
            raf.read(data);
            String nickname = new String(data,"UTF-8").trim();

            //读取年龄
            int age = raf.readInt();
            System.out.println("username :" + username + " ,password : " + password +" ,nickname :" + nickname +" ,age :"+ age);
            //System.out.println(Arrays.toString(data));
            System.out.println(raf.getFilePointer());
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值