[Java开发之路](7)RandomAccessFile类详解

简介:


RandomAccessFile适用于大小已知的记录组成的文件, 提供的对文件访问,既可以读文件,也可以写文件,并且支持随机访问文件,可以访问文件的任意位置 。文件中记录的大小不一定都相同,只要我们知道记录的大小和位置。但是该类仅限于操作文件。

RandomAccessFile 不属于InputStream和OutputStream继承层次结构中的一部分。除了 实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个继承层次结构没有任何关系,它甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类,从头开始编写其所有的方法(大多数都是本地的)。这么做是因为RandomAccessFile拥有和别的IO类型本质上不同的行为,因为我们可以 在一个文件内向前和向后移动。它是一个直接继承Object的,独立的类。

本质上说,RandomAccessFile的工作方式类似于把DataInputStream和DataOutputStream结合起来,还添加了一些方法,其中方法getFilePointer( )用来查找当前所处的文件位置,seek( )用来在文件内移至新的位置,length( )用来 判断文件大小 。此外,它的构造方法还需要一个参数来表示打开模式(只读方式 r 读写方式 rw),它不支持只写文件。

只有RandomAccessFile支持搜寻方法(seek()),并且这个方法也只适用于文件。BufferedInputStream却只能允许标注( mark() )位置( 其值存储在内部某个变量内 )和重新设定位置(reset()),但是这些功能有限,不是非常实用。

在JDK 1.4中, RandomAccessFile的绝大多数功能(但不是全部)已经被 nio内存映射文件给取代了。

方法:

方法 描述
void close() 关闭此随机访问文件流并释放与该流关联的所有系统资源。
FileChannel getChannel () 返回与此文件关联的唯一 FileChannel 对象。
FileDescriptor getFD () 返回与此流关联的不透明文件描述符对象。
long getFilePointer () 返回此文件中的当前偏移量,用来查找当前所处的位置。
long length() 返回此文件的长度。
int read() 从此文件中读取一个数据字节
int read(byte[] b) 将最多 b.length 个数据字节从此文件读入 byte 数组。
int read(byte[] b,int off,int len) 将最多 len 个数据字节从此文件读入 byte 数组。
boolean readBoolean() 从此文件读取一个 boolean。
byte readByte() 从此文件读取一个有符号的八位值。
char readChar() 从此文件读取一个字符
double readDouble() 从此文件读取一个 double。
float readFloat() 从此文件读取一个 float。
void readFully(byte[] b) 将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始。
void readFully(byte[] b,int off,int len) 将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始。
int readInt() 从此文件读取一个有符号的 32 位整数。
String readLine() 从此文件读取文本的下一行。
long readLong() 从此文件读取一个有符号的 64 位整数。
short readShort() 从此文件读取一个有符号的 16 位数。
int readUnsignedByte() 从此文件读取一个无符号的八位数
int readUnsignedShort() 从此文件读取一个无符号的 16 位数。
String readUTF() 从此文件读取一个字符串。
void seek(long pos) 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
void setLength(long newLength) 设置此文件的长度。
int skipBytes(int n) 尝试跳过输入的 n 个字节以丢弃跳过的字节。
void write(byte[] b) 将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。
void write(byte[] b, int off, int len) 将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。
void write(int b) 向此文件写入指定的字节。
void writeBoolean(boolean v) 按单字节值将 boolean 写入该文件。
void writeByte(int v) 按单字节值将 byte 写入该文件
void writeBytes(String s) 按字节序列将该字符串写入该文件。
void writeChar(int v) 按双字节值将 char 写入该文件,先写高字节。
void writeChars(String s) 按字符序列将一个字符串写入该文件。
void writeDouble(double v) 使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节。
void writeFloat(float v) 使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节。
void writeInt(int v) 按四个字节将 int 写入该文件,先写高字节。
void writeLong(long v) 按八个字节将 long 写入该文件,先写高字节
void writeShort(int v) 按两个字节将 short 写入该文件,先写高字节。
void writeUTF(String str) 使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。



案例:

 
  
package com.qunar.bean;
 
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Arrays;
 
public class FileDemo {
public static void main(String[] args) {
String pathname = "D:\\Recommended system.txt";
// 创建文件实例
File file = new File(pathname);
try {
// 判断文件是否存在
if(!file.exists()){
file.createNewFile();
}//if
// 读写方式打开文件
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
// write 从当前指针开始写入,写入一个字节
randomAccessFile.write('A');
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
randomAccessFile.write('B');
int num = 0x7fffffff;
// 如果用write方法,每次只能写一个字节,需要写4次
randomAccessFile.write(num >>> 24);
randomAccessFile.write(num >>> 16);
randomAccessFile.write(num >>> 8);
randomAccessFile.write(num);
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
// 或者是用writeInt方法 一次写入
randomAccessFile.writeInt(num);
System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer());
// 文件指针指向文件开头
randomAccessFile.seek(0);
// 一次性读取 把文件中内容都读到字节数组中
byte[] buffer = new byte[(int)randomAccessFile.length()];
randomAccessFile.read(buffer);
for (byte b : buffer) {
// 16进制输出
System.out.print(Integer.toHexString(b)+" ");
}//for
randomAccessFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
 
   
package com.qunar.bean;
 
import java.io.File;
import java.io.RandomAccessFile;
 
public class FileDemo {
public static void main(String[] args) {
String pathname = "D:\\Recommended system.txt";
// 创建文件实例
File file = new File(pathname);
try {
// 判断文件是否存在
if(!file.exists()){
file.createNewFile();
}//if
// 读写方式打开文件
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
// 写值
for(int i = 0;i < 5;++i){
randomAccessFile.writeInt(i);
}//for
// 将文件指针移到第二个Int值后
randomAccessFile.seek(2*4);
// 覆盖第三个Int值
randomAccessFile.writeInt(6);
// 文件指针指向文件开头
randomAccessFile.seek(0);
// 输出
for (int i = 0;i < 5;++i) {
System.out.print(randomAccessFile.readInt()+" ");
}//for
randomAccessFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

 
  
package com.qunar.bean;
 
import java.io.File;
import java.io.RandomAccessFile;
 
public class FileDemo {
public static void main(String[] args) {
String pathname = "D:\\Recommended system.txt";
// 创建文件实例
File file = new File(pathname);
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
// 以下向file文件中写数据
// 占4个字节
randomAccessFile.writeInt(2015);
// 占8个字节
randomAccessFile.writeDouble(12.23);
// 占2个字节
randomAccessFile.writeShort(19);
System.out.println("当前位置:"+randomAccessFile.getFilePointer());
randomAccessFile.writeUTF("欢迎来到小斯的博客");
System.out.println("当前位置:"+randomAccessFile.getFilePointer());
// 占2个字节
randomAccessFile.writeChar('Y');
System.out.println("当前位置:"+randomAccessFile.getFilePointer());
randomAccessFile.writeUTF("小斯的博客欢迎你");
// 把文件指针位置设置到文件起始处
randomAccessFile.seek(0);
System.out.println("读取一个Int值:"+randomAccessFile.readInt());
System.out.println("读取一个Double值:"+randomAccessFile.readDouble());
System.out.println("读取一个Short值:"+randomAccessFile.readShort());
System.out.println("读取一个字符串:"+randomAccessFile.readUTF());
// 将文件指针跳过2个字节
randomAccessFile.skipBytes(2);
System.out.println("读取一个字符串:"+randomAccessFile.readUTF());
randomAccessFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}









目录
相关文章
|
2月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
12天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
2月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
160 57
|
13天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
59 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
23天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
107 13
|
27天前
|
算法 Java API
如何使用Java开发获得淘宝商品描述API接口?
本文详细介绍如何使用Java开发调用淘宝商品描述API接口,涵盖从注册淘宝开放平台账号、阅读平台规则、创建应用并申请接口权限,到安装开发工具、配置开发环境、获取访问令牌,以及具体的Java代码实现和注意事项。通过遵循这些步骤,开发者可以高效地获取商品详情、描述及图片等信息,为项目和业务增添价值。
59 10
|
21天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
57 2
|
30天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
2月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
66 8