首页 > 编程语言 >Java IO详解(七)------随机访问文件流

Java IO详解(七)------随机访问文件流

时间:2022-10-05 14:05:22浏览次数:65  
标签:Java 字节 写入 System RandomAccessFile ras IO ------ new

1、什么是 随机访问文件流 RandomAccessFile?

  该类的实例支持读取和写入随机访问文件。 随机访问文件的行为类似于存储在文件系统中的大量字节。 有一种游标,或索引到隐含的数组,称为文件指针 ; 输入操作读取从文件指针开始的字节,并使文件指针超过读取的字节。 如果在读/写模式下创建随机访问文件,则输出操作也可用; 输出操作从文件指针开始写入字节,并将文件指针提前到写入的字节。 写入隐式数组的当前端的输出操作会导致扩展数组。 文件指针可以通过读取getFilePointer方法和由设置seek方法。

  通俗来讲:我们以前讲的 IO 字节流,包装流等都是按照文件内容的顺序来读取和写入的。而这个随机访问文件流我们可以再文件的任意地方写入数据,也可以读取任意地方的字节。

 

我们查看 底层源码,可以看到:

public class RandomAccessFile implements DataOutput, DataInput, Closeable {

  实现了 DataOutput类,DataInput类,那么这两个类是什么呢?

 

2、数据流:DataOutput,DataInput

  ①、DataOutput:提供将数据从任何Java基本类型转换为一系列字节,并将这些字节写入二进制流。 还有一种将​​String​​转换为modified UTF-8格式(这种格式会在写入的数据之前默认增加两个字节的长度)并编写结果字节系列的功能。

  ②、DataInput:提供从二进制流读取字节并从其中重建任何Java原语类型的数据。 还有,为了重建设施String从数据modified UTF-8格式。 

下面我们以其典型实现:DataOutputSteam、DataInputStream 来看看它的用法:

//数据输出流
File file = new File("io"+File.separator+"a.txt");
DataOutputStream dop = new DataOutputStream(new FileOutputStream(file));
//写入三种类型的数据
dop.write(65);
dop.writeChar('哥');
dop.writeUTF("帅锅");
dop.close();

//数据输入流
DataInputStream dis = new DataInputStream(new FileInputStream(file));
System.out.println(dis.read()); //65
System.out.println(dis.readChar()); //哥
System.out.println(dis.readUTF()); //帅锅
dis.close();

  

 

3、通过上面的例子,我们可以看到因为 RandomAccessFile 实现了数据输入输出流,那么 RandomAccessFile 这一个类就可以完成 输入输出的功能了。

  

Java IO详解(七)------随机访问文件流_文件指针

这里面第二个参数:String mode 有以下几种形式:(ps:为什么这里的值是固定的而不弄成枚举形式,不然很容易写错,这是因为随机访问流出现在枚举类型之前,属于Java 历史遗留问题)

  

Java IO详解(七)------随机访问文件流_数据_02

 

 第一种:用 随机流顺序读取数据

public class RandomAccessFileTest {
public static void main(String[] args) throws Exception {
File file = new File("io"+File.separator+"a.txt");
write(file);
read(file);
}

/**
* 随机流读数据
*/
private static void read(File file) throws Exception {
//以 r 即只读的方法读取数据
RandomAccessFile ras = new RandomAccessFile(file, "r");
byte b = ras.readByte();
System.out.println(b); //65

int i = ras.readInt();
System.out.println(i); //97

String str = ras.readUTF(); //帅锅
System.out.println(str);
ras.close();
}

/**
* 随机流写数据
*/
private static void write(File file) throws Exception{
//以 rw 即读写的方式写入数据
RandomAccessFile ras = new RandomAccessFile(file, "rw");
ras.writeByte(65);
ras.writeInt(97);
ras.writeUTF("帅锅");

ras.close();
}

}

  

第二种:随机读取,那么我们先介绍这两个方法

Java IO详解(七)------随机访问文件流_文件指针_03

Java IO详解(七)------随机访问文件流_数据_04

这里所说的偏移量,也就是字节数。一个文件是有N个字节数组成,那么我们可以通过设置读取或者写入的偏移量,来达到随机读取或写入的目的。

我们先看看Java 各数据类型所占字节数:

Java IO详解(七)------随机访问文件流_偏移量_05

下面是 随机读取数据例子:

/**
* 随机流读数据
*/
private static void read(File file) throws Exception {
//以 r 即只读的方法读取数据
RandomAccessFile ras = new RandomAccessFile(file, "r");

byte b = ras.readByte();
System.out.println(b); //65
//我们已经读取了一个字节的数据,那么当前偏移量为 1
System.out.println(ras.getFilePointer()); //1
//这时候我们设置 偏移量为 5,那么可以直接读取后面的字符串(前面是一个字节+一个整型数据=5个字节)
ras.seek(5);
String str = ras.readUTF(); //帅锅
System.out.println(str);

//这时我们设置 偏移量为 0,那么从头开始
ras.seek(0);
System.out.println(ras.readByte()); //65

//需要注意的是:UTF 写入的数据默认会在前面增加两个字节的长度

ras.close();
}

  

 随机流复制文件:

/**
* 随机流复制文件
* @param fileA
* @param B
* @throws Exception
*/
private static void copyFile(File fileA,File fileB) throws Exception{

RandomAccessFile srcRA = new RandomAccessFile(fileA, "rw");
RandomAccessFile descRA = new RandomAccessFile(fileB, "rw");

//向 文件 a.txt 中写入数据
srcRA.writeByte(65);
srcRA.writeInt(97);
srcRA.writeUTF("帅锅");
//获取 a.txt 文件的字节长度
int len = (int) srcRA.length();
srcRA.seek(0);
System.out.println(srcRA.readByte()+srcRA.readInt()+srcRA.readUTF());

//开始复制
srcRA.seek(0);
//定义一个数组,用来存放 a.txt 文件的数据
byte[] buffer = new byte[len];
//将 a.txt 文件的内容读到 buffer 中
srcRA.readFully(buffer);
//再将 buffer 写入到 b.txt文件中
descRA.write(buffer);

//读取 b.txt 文件中的数据
descRA.seek(0);
System.out.println(descRA.readByte()+descRA.readInt()+descRA.readUTF());
//关闭流资源
srcRA.close();
descRA.close();
}

  

ps:一般多线程下载、断点下载都可以运用此随机流

 



标签:Java,字节,写入,System,RandomAccessFile,ras,IO,------,new
From: https://blog.51cto.com/u_15707676/5732595

相关文章

  • 认识 Iconfont 以及什么是 .eot、.woff、.ttf、.svg
    一、Iconfont1.概述在前端作业中,二十年前只有页面中铺满文字就算上线产品,现如今,不加点俏皮的“图标”会让页面显得很Low很Low。 图标在写这篇文章之前,我一直以为上图中......
  • MYSQL学习之视图
    (一)什么是视图??  视图就是站在不同的角度取看待同一份数据。(二)基本操作表复制:mysql>createtabledept2asselect*fromdept;#复制mysql>createtablescholar1assel......
  • 通过JDBC进行简单的增删改查(以MySQL为例)
    目录前言:什么是JDBC一、准备工作(一):MySQL安装配置和基础学习二、准备工作(二):下载数据库对应的jar包并导入三、JDBC基本操作(1)定义记录的类(可选)(2)连接的获取(3)insert(4)upda......
  • 网页录像录音功能的实现之MediaRecorder的使用
    前面介绍了通过H5实现在网页内打开摄像头和麦克风,实现截图和图像预览的相关知识。getUserMediaAPI及HTML5调用摄像头和麦克风一个简单的demo 实现摄像头的调用及视频录......
  • 年薪80万+年终奖汽车|显扬科技招聘三维机器视觉研发总监、高级三维算法工程师
    显扬科技专注研发并产业化高速高清三维机器视觉设备,致力于成为全球领先的三维机器视觉设备提供商。显扬科技研发的三维机器视觉设备精度能达微米级,采集速度高达300帧,主要应......
  • PM2用法简介
    简介PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。引用全局安装​​sudonpminstallpm2@latest......
  • Ajax关于readyState(状态值)和status(状态码)的研究
    vargetXmlHttpRequest=function(){try{//主流浏览器提供了XMLHttpRequest对象returnnewXMLHttpRequest();}catch(e){//低版本的IE......
  • js:防抖动与节流
    针对一些会频繁触发的事件如scroll、resize,如果正常绑定事件处理函数的话,有可能在很短的时间内多次连续触发事件,十分影响性能。因此针对这类事件要进行防抖动或者节流处理防......
  • 线程之间的通信
    一、为什么要线程通信?  1.多个线程并发执行时,在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务, 并且我们希望他们有规律的执行,那么多线程......
  • 使用npm安装一些包失败了的看过来(npm国内镜像介绍)
    镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在):1.通过config命令npmconfigset://registry.npm.taobao.org(如果上面配置正确这......