• IO包中的RandomAccessFile类


    RandomAccessFile

      RandomAccessFile 是随机访问文件的类。它支持对文件随机访问的读取和写入,即我们也可以从指定的位置读取/写入文件数据,因为该类在其内部封装了一个数组和指针,当要用该类的对象读取文件中的元素时,就将要读取的元素先存储在数组中,而get方法和set方法也就是读和写操作。
      需要注意的是,RandomAccessFile 虽然属于java.io包(因为它具备读和写的功能),但它不是InputStream或者OutputStream的子类; FileInputStream 只能对文件进行读操作,而FileOutputStream 只能对文件进行写操作;但是,RandomAccessFile 同时支持文件的读和写,并且它支持随机访问,原理在于RandomAccessFile内部封装了FileInputStream和FileOutputStream。

      虽然RandomAccessFile 可以同时对文件进行读取和写入,但是它却有一个较大的局限性,那就是它只能操作文件,也就是说只能操作硬盘上的数据,而不能操作内存,控制台上的数据。

    构造函数:

      

      

      

    1. RandomAccessFile 模式说明

    RandomAccessFile共有4种模式:"r", "rw", "rws"和"rwd"。

    "r"    以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。  
    "rw"   打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
    "rws"  打开以便读取和写入。相对于 "rw","rws" 还要求对“文件的内容”或“元数据”的每个更新都同步写入到基础存储设备。  
    "rwd"  打开以便读取和写入,相对于 "rw","rwd" 还要求对“文件的内容”的每个更新都同步写入到基础存储设备。  

     说明

    (01) 什么是“元数据”,即metadata?

      metadata是“关于数据的数据”。在文件系统中,数据被包含在文件和文件夹中;metadata信息包括:“数据是一个文件,一个目录还是一个链接”,“数据的创建时间(简称ctime)”,“最后一次修改时间(简称mtime)”,“数据拥有者”,“数据拥有群组”,“访问权限”等等。

    (02) "rw", "rws", "rwd" 的区别。
    当操作的文件是存储在本地的基础存储设备上时(如硬盘, NandFlash等),"rws" 或 "rwd", "rw" 才有区别。
    当模式是 "rws" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]” 或 “修改文件元数据(如文件的mtime)”时,都会将这些改变同步到基础存储设备上。
    当模式是 "rwd" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]”时,都会将这些改变同步到基础存储设备上。
    当模式是 "rw" 并且 操作的是基础存储设备上的文件;那么,关闭文件时,会将“文件内容的修改”同步到基础存储设备上。至于,“更改文件内容”时,是否会立即同步,取决于系统底层实现。

    注意:该对象在实例化时,如果要操作的文件不存在,不管是读操作还是写操作,都会自动创建文件;如果文件存在,写数据时未指定位置,会从头开始写,即覆盖原有的内容(注意只覆盖自己写入的位置)。可以用于多线程下载或多个线程同时写数据到文件。

      【代码演示】

     1 import java.io.IOException;
     2 import java.io.RandomAccessFile;
     3 public class RandomAccessFileWriteDemo {
     4     public static void main(String[] args)throws IOException {
     5         RandomAccessFile rafw=new RandomAccessFile("c:\html\test\r.txt","rw");
     6         //文件不存在,则自动创建,当文件存在时,会覆盖原有的文件,注意只是覆盖自己写入的部分。
     7         rafw.write("sdfghjk".getBytes());//注意要进行写操作时,构造函数的mode必须设置为rw,否则报错:拒绝访问。
     8         //rafw.writeInt(17);//注意write方法只写入最低八位,会造成数据丢失,因此选用writeInt方法
     9         rafw.close();
    10         RandomAccessFile rafr=new RandomAccessFile("c:\html\test\r.txt","rw");
    11         rafr.seek(3);//可以调节指针的位置,传入3,则表示从三号位置开始读取,默认指针是从0开始
    12         byte[] buff=new byte[8];
    13         int num;
    14         while ((num=rafr.read(buff))!=-1){
    15             System.out.print(new String(buff,0,num));
    16         }
    17         rafr.close();
    18     }
    19 }

      【代码演示】:往文件的指定位置插入内容,且不能覆盖原来的内容。

     1 import java.io.FileInputStream;
     2 import java.io.FileOutputStream;
     3 import java.io.IOException;
     4 import java.io.RandomAccessFile;
     5 import java.util.Scanner;
     6 
     7 public class insertData {
     8     public static void main(String[] args) {
     9         Scanner in=new Scanner(System.in);
    10         System.out.println("请输入文件存放的路径:");
    11         String path=in.nextLine();
    12         System.out.println("请输入要插入的位置:");
    13         Long points=in.nextLong();
    14         in.nextLine();//缓冲回车键
    15         System.out.println("请输入要插入的内容:");
    16         String insertContent=in.nextLine();
    17         try{
    18             randomInserst(path,points,insertContent);
    19         }catch (IOException e){
    20             System.out.println("插入失败");
    21         }
    22 
    23     }
    24     public static void  randomInserst(String path,Long points,String insertContent)throws IOException {
    25         RandomAccessFile  raf=new RandomAccessFile(path,"rw");
    26         raf.seek(points);//调节指针位置
    27         FileOutputStream fos=new FileOutputStream("c:\html\test\tmp.txt");//临时文件
    28         byte[] buff=new byte[12];
    29         int num;
    30         while ((num=raf.read(buff))!=-1){//将指针后面的内容先存储到临时文件中
    31             fos.write(buff,0,num);//避免脏读
    32         }
    33         raf.seek(points);//因为指针会随着读取数据移动,最终到末尾,所以要重新调节指针位置
    34         raf.writeBytes(insertContent);//将要写的内容插入
    35         FileInputStream fis=new FileInputStream("c:\html\test\tmp.txt");//读取临时文件
    36         byte[] buff2=new byte[12];
    37         int num2;
    38         while ((num2=fis.read(buff2))!=-1){//将指针后面的内容先存储到临时文件中
    39             raf.write(buff2,0,num2);
    40         }
    41         fis.close();
    42         fos.close();
    43         raf.close();
    44     }
    45 }
  • 相关阅读:
    lombok 下的@Builder注解用法
    (springboot)自定义Starter
    各种 Spring-Boot-Starters系列 介绍
    MQ的使用场景
    SpringBoot中使用rabbitmq,activemq消息队列和rest服务的调用
    RPC原理详解
    Java性能优化的50个细节
    thinkphp3.2.2有预览的多图上传
    关于php中的exec命令
    关于thinkphp3.1无法加载模块解决办法
  • 原文地址:https://www.cnblogs.com/ljl150/p/12370576.html
Copyright © 2020-2023  润新知