Java IO(二)——RandomAccessFile
一、RandomAccessFile
RandomAccessFile类可以说是Java语言中功能最为丰富的文件访问类,它提供了众多的文件访问方法。RandomAccessFile类支持"随机访问"方式,可以跳转到文件的任意位置处读写数据。要访问一个文件的时候,不想把文件从头读到尾,而是希望像访问一个数据库一样地访问一个文本文件,使用RandomAccessFile类是最佳选择。
RandomAccessFile对象类中有个位置指示器,指向当前读写处的位置,当读写n个字节后,文件指示器将指向这n个字节后的下一个字节处。刚打开文件时,文件指示器指向文件的开头处,可以移动文件指示器到新的位置,随后的读写将从新的位置开始。
RandomAccessFile类在文件随机(相对于顺序)读取时有很大的优势,但该类仅限于操作文件,不能访问其他得IO设备,如网络、内存映像等。
二、RandomAccessFile构造方法
RandomAccessFile类为用户提供了两种构造方法:
1、RandomAccessFile(File file, String mode)
2、RandomAccessFile(String name, String mode)
其实第二种构造方法也是new一个File出来再调用第一种构造方法,建议使用第一种构造方法,因为第一篇文章就说了File是IO的基础,有一个File不仅仅可以通过RandomAccessFile对文件进行操作,也可以通过File对象对文件进行操作。至于mode,Java给开发者提供了四种mode:
| 模 式 | 作 用 |
| r | 表示以只读方式打开,调用结果对象的任何write方法都将导致抛出IOException |
| rw | 打开以便读取和写入,如果该文件尚不存在,则尝试创建该文件 |
| rws | 打开以便读取和写入,相对于"rw",还要求对文件内容或元数据的每个更新都同步写入到底层存储设备 |
| rwd | 打开以便读取和写入,相对于"rw",还要求对文件内容的每个更新都同步写入到底层存储设备 |
注意第二点"rw"模式,对rw模式的解释意味着Java并不强求指定的路径下一定存在某个文件,假如文件不存在,会自动创建。
三、RandomAccessFile中的方法
RandomAccessFile中有如下一些常用方法:
| 方 法 | 作 用 |
| void close() | 重要,关闭此随机访问文件流并释放与该流关联的所有系统资源 |
| FileChannel getChannel() | 返回与此文件关联的唯一FileChannel对象,NIO用到 |
| long getFilePointer() | 返回此文件中的当前偏移量 |
| long length() | 返回此文件的长度 |
| int read() | 从此文件中读取一个数据字节 |
| int read(byte[] b) | 将最多b.length个数据字节从此文件读入byte数组,返回读入的总字节数,如果由于已经达到文件末尾而不再有数据,则返回-1。在至少一个输入字节可用前,此方法一直阻塞 |
| int read(byte[] b, int off, int len) | 将最多len个数据字节从此文件的指定初始偏移量off读入byte数组 |
| boolean readBoolean() | 从此文件读取一个boolean,其余readByte()、readChar()、readDouble()等类似 |
| String readLine() | 从此文件读取文本的下一行 |
| void seek(long pos) | 重要,设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作 |
| 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写入该文件,其余writeByte(int v)、writeBytes(String s)、writeChar(int v)等都类似 |
三、RandomAccessFile使用实例
先定义一个实体类:
package com.demo.entity;
public class Employee {
private String name;
private int age;
private final static int LEN = 8;
public Employee() {
}
public Employee(String name, int age) {
if (name.length() > LEN) {
name = name.substring(0, 8);
} else {
while (name.length() < LEN) {
name = name + "\u0000";
}
}
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
第一部分,写文件,该文件在路径下并没有,所以Java会自动帮我们创建:
/**
* 写文件
*/
@Test
public void writeFile() throws IOException{
Employee e1 = new Employee("zhangsan", 23);
Employee e2 = new Employee("lisi", 24);
Employee e3 = new Employee("wangwu", 25); RandomAccessFile raf0 = new RandomAccessFile("D:/Files/employee.txt", "rw");
raf0.writeBytes(e1.getName());
raf0.writeInt(e1.getAge());
raf0.writeBytes(e2.getName());
raf0.writeInt(e2.getAge());
raf0.writeBytes(e3.getName());
raf0.writeInt(e3.getAge());
raf0.close();
}
文件创建好了,D盘下的Files文件夹也有该文件了,所以读取一下,这里使用了一些小技巧来演示seek方法和skipBytes方法:
/**
* 读文件
*/
@Test
public void ReadFile() throws IOException{
RandomAccessFile raf1 = new RandomAccessFile("D:/Files/employee.txt", "r");
int len = 8;
raf1.skipBytes(12); // 跳过第一个员工的信息,其姓名8字节,年龄4字节
System.out.println("第二个员工的信息:");
String str = "";
for (int i = 0; i < len; i++)
{
str = str + (char)raf1.readByte();
}
System.out.println("name:" + str);
System.out.println("age:" + raf1.readInt());
System.out.println("第一个员工的信息:");
raf1.seek(0);
str = "";
for (int i = 0; i < len; i++)
{
str = str + (char)raf1.readByte();
}
System.out.println("name:" + str);
System.out.println("age:" + raf1.readInt());
System.out.println("第三个员工的信息:");
raf1.skipBytes(12); // 跳过第二个员工的信息
str = "";
for (int i = 0; i < len; i++)
{
str = str + (char)raf1.readByte();
}
System.out.println("name:" + str.trim());
System.out.println("age:" + raf1.readInt());
raf1.close();
}
看一下运行结果:
第二个员工的信息:
name:lisi
age:24
第一个员工的信息:
name:zhangsan
age:23
第三个员工的信息:
name:wangwu
age:25
可能有人奇怪,"zhangsan"加上一个int跳过12个字节可以理解,但是"lisi"、"wangwu"为什么加上int要跳过12个字节呢?明明"lisi"只有4个字节,"wangwu"只有6个字节啊。这个就涉及到一个"字节对齐"的问题了,有兴趣的可以了解一下。另外,再说一下,RandomAccessFile使用完一定要及时close()。
Java IO(二)——RandomAccessFile的更多相关文章
- Java IO(二)--RandomAccessFile基本使用
RandomAccessFile: 翻译过来就是任意修改文件,可以从文件的任意位置进行修改,迅雷的下载就是通过多个线程同时读取下载文件.例如,把一个文件分为四 部分,四个线程同时下载,最后进行内容拼接 ...
- 图解 Java IO : 二、FilenameFilter源码
Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter ...
- Java IO的RandomAccessFile的使用(转)
现有如下的一个需求,向已存在1G数据的txt文本里末尾追加一行文字,内容如下“Lucene是一款非常优秀的全文检索库”.可能大多数朋友会觉得这个需求很easy,说实话,确实easy,然后XXX君开始实 ...
- Java—IO流 RandomAccessFile类
RandomAccessFile java提供的对文件内容的访问,既可以读文件,也可以写文件. 支持随机访问文件,可以访问文件的任意位置. java文件模型,在硬盘上的文件是byte byte byt ...
- Java IO 之 RandomAccessFile 操作文件内容
RandomAccessFile类实现对文件内容的随机读写 文件内容的随机操作,重难点在于字符操作,具体查看API package org.zln.io.file; import java.io.IO ...
- Java IO(二)
字节流 字符流: FileReader FileWriter BufferedReader BufferedWriter 字节流: FileInputStream FileOutputStream B ...
- java IO(二):字节流
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- Java IO(二) 之 InputStream
源代码均以JDK1.8作为參考 前言: InputStream实现了两个接口Closeable和AutoCloseable: Closeable:JDK1.5中引入,Closeable接口中仅仅有一个 ...
- Java IO学习--RandomAccessFile
1.什么是 随机访问文件流 RandomAccessFile 这个类在很多资料上翻译成中文都是:随机访问文件,在中文里,随机是具有不确定的含义,指一会访问这里,一会访问那里的意思.如果以这种语义来解释 ...
- 系统学习 Java IO (二)----IO 异常处理
目录:系统学习 Java IO---- 目录,概览 我们使用流后,需要正确关闭 Streams 和 Readers / Writers . 这是通过调用 close() 方法完成的,看看下面这段代码: ...
随机推荐
- PHP对接淘宝客api完成APP引流优惠券
淘宝客现在对多数人来说已经耳熟能详了,属于CPS(Cost Per Sale),一种网络广告收费标准,以实际销售产品数量来换算广告刊登金额.其他收费标准还有常见的CPC(Cost Per Click ...
- Python Elasticsearch批量操作客户端
基于Python实现的Elasticsearch批量操作客户端 by:授客 QQ:1033553122 1. 代码用途 1 2. 测试环境 1 3. 使用方法 1 3.1 配置ES服务器信息 1 ...
- 在Win32程序中嵌入Edge浏览器组件
代码未经测试,只做个记录 据说只是改了UA. 在注册表修改这个路径,并且把自己程序添加进去,写一个浏览器控件的版本号,只要高于12000就自动改为Edge. For 64bit application ...
- ORA-1652: unable to extend temp segment by 128 in tablespace xxx Troubleshootin
当收到告警信息ORA-01652: unable to extend temp segment by 128 in tablespace xxxx 时,如何Troubleshooting ORA-16 ...
- mssql sqlserver 获取指定日期为本月第几个工作日
转自:http://www.maomao365.com/?p=6771 摘要: 下文讲述工作中,需要获取指定日期在当月的工作日 下文讲述常规的指定工作日所在月的天数分析,实现思路:1 生成一个国家法定 ...
- python len()函数的用法
函数:len() 返回字符串.列表.字典.元组等长度. 语法:len(str) str:要计算的字符串.列表.字典.元组等 返回值:字符串.列表.字典.元组等元素的长度. Test: 1:计算字符串的 ...
- Docker 从入门到实践(一)Docker 简介
读前须知:本教程大部分都是[Docker 从入门到实践 ]一书的知识,有兴趣可以直接观看书籍.同时,借鉴书籍的知识,如有侵权,请告知我,我会删除处理.谢谢. 一.什么是 Docker? Docker ...
- ASP.NET -- WebForm -- Cookie的使用
ASP.NET -- WebForm -- Cookie的使用 Cookie是存在浏览器内存或磁盘上. 1. Test3.aspx文件 <%@ Page Language="C#&q ...
- Linux 小知识翻译 - 「如何成为 Linux 内核开发者」
新年的开始,聊聊「怎么做才能成为Linux内核开发者」. Linux内核的开发都是由志愿开发者们完成的.他们并不属于某些特定的企业. 因此,你也有参加Linux内核开发的资格.不用说,卓越的编码技术以 ...
- Java程序导出成.jar文件、生成.exe可执行文件及打包成可执行安装程序(可在无Java环境的计算机上运行)--以个人所得税计算器为例
Java程序导出成.jar文件.生成.exe可执行文件及打包成可执行安装程序 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 需要准备的软件: jdk, ...