一、前言

  本来在研究NIO,别人举的栗子里面,看到一个RandomAccessFile类,之前没见过,就去看了一下,现将相关内容记录如下

二、正文

  RandomAccessFile直接继承自Object,并且实现DataInput和DataOutput接口,它不属于InputStream和OutputStream类系的,并不是针对流的操作,它能在读取文件的时候前后移动,这个是和其他针对流操作的I/O类的本质区别。

  基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream粘起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样),它不支持只写文件。它支持对文件随机访问的读取和写入,即我们可以在指定的位置从文件读取/写入数据。

  平时,我们如果要往一个文件末尾追加一些数据,我们会将文件加载到内存,然后进行操作,但是如果文件本身非常大,比如好几G的量,那么普通的电脑承受不了,我们这时就可以使用RandomAccessFile,它无需将文件内容加载在内存,便可以在文件末尾追加内容。当然,有可能很多人会问,这个RandomAccessFile可以在文件指定位置插入数据吗?答案是:RandomAccessFile只能在指定位置修改数据,并不能插入数据(据我所知貌似没有哪个类支持在某个文件某个位置插入数据吧)。

  RandomAccessFile在读取等长数据的情况下也有优势。

  下面给出RandomAccessFile相关使用实例,先看下要操作的文件内容:

  

  

//实例一,从指定位置读取文件
package com.randomaccessfile.demo; import java.io.RandomAccessFile; /**
*
* @author cyg
* @date 2017-6-3 下午02:33:13
* @description 随机读取文件的内容
*/
public class Demo1 {
public static void main(String[]args) throws Exception{
//文件内容:hello world!
RandomAccessFile raf = new RandomAccessFile("C:\\Users\\jackalc\\Desktop\\demo.txt", "r");
System.out.println("在未指定位置之前,文件指针:"+raf.getFilePointer());
raf.seek(6);//指定文件指针位置,从0开始
System.out.println("在指定位置之后,文件指针:"+raf.getFilePointer());
int readLength = 0;
byte [] bytes = new byte[1024];
while((readLength=raf.read(bytes))>0){
System.out.println(new String(bytes,0,readLength));
}
}
} //输出
在未指定位置之前,文件指针:0
在指定位置之后,文件指针:6
world!
//实例二,文件末尾追加内容
package com.randomaccessfile.demo; import java.io.RandomAccessFile; /**
*
* @author cyg
* @date 2017-6-3 下午02:33:13
* @description 文件末尾追加内容
*/
public class Demo2 {
public static void main(String[]args) throws Exception{
//文件内容:hello world!
RandomAccessFile raf = new RandomAccessFile("C:\\Users\\jackalc\\Desktop\\demo.txt", "rw");//读写方式打开
raf.seek(raf.length());//将文件的指针移动到原先内容最后一个字节的后面
raf.write("最末尾追加的内容".getBytes());
}
}

  实例二运行后,文件内容变更为:

  

//实例三,在文件指定位置修改文件
package com.randomaccessfile.demo; import java.io.RandomAccessFile; /**
*
* @author cyg
* @date 2017-6-3 下午02:33:13
* @description 在文件指定位置修改文件
*/
public class Demo3 {
public static void main(String[]args) throws Exception{
//文件内容:hello world!
RandomAccessFile raf = new RandomAccessFile("C:\\Users\\jackalc\\Desktop\\demo.txt", "rw");//读写方式打开
raf.seek(6);//"6"是“w”所在的位置
raf.write("我现在在指定的位置修改内容,我会覆盖从指定位置开始,和我等长的文件内容!".getBytes());
}
}

  实例三运行之后,文件内容变更成这样:

  如果想要在文件指定位置插入数据,而不是修改数据,要怎么操作呢?RandomAccessFile并没有提供这个方法,对于这个需求,我们可以将指定位置后面的内容先存储到临时文件里面,然后等内容插入完,我们再将临时文件的内容插入到刚刚插入的内容后面,贴一下别人的代码(原文见“三、连接”处):

//实例四,在文件指定位置插入内容
package com.randomaccessfile.demo; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile; /**
*
* @author cyg
* @date 2017-6-3 下午02:33:13
* @description 在文件指定位置插入内容
*/
public class Demo4 {
public static void main(String[] args) {
//文件内容:hello world!
String path="C:\\Users\\jackalc\\Desktop\\demo.txt";
insert(path, 6, "这是我需要插入的内容,不覆盖原先的内容");
}
/**
* 实现向指定位置
* 插入数据
* @param fileName 文件名
* @param points 指针位置
* @param insertContent 插入内容
* **/
public static void insert(String fileName,long points,String insertContent){
try{
File tmp=File.createTempFile("tmp", null);
tmp.deleteOnExit();//在JVM退出时删除 RandomAccessFile raf=new RandomAccessFile(fileName, "rw");
//创建一个临时文件夹来保存插入点后的数据
FileOutputStream tmpOut=new FileOutputStream(tmp);
FileInputStream tmpIn=new FileInputStream(tmp);
raf.seek(points);
/**将插入点后的内容读入临时文件夹**/ byte [] buff=new byte[1024];
//用于保存临时读取的字节数
int hasRead=0;
//循环读取插入点后的内容
while((hasRead=raf.read(buff))>0){
// 将读取的数据写入临时文件中
tmpOut.write(buff, 0, hasRead);
} //插入需要指定添加的数据
raf.seek(points);//返回原来的插入处
//追加需要追加的内容
raf.write(insertContent.getBytes());
//最后追加临时文件中的内容
while((hasRead=tmpIn.read(buff))>0){
raf.write(buff,0,hasRead);
}
}catch(Exception e){
e.printStackTrace();
}
}
}

  实例四运行完之后,文件内容如下:

三、链接

1、http://blog.csdn.net/czplplp_900725/article/details/37809579

2、http://www.cnblogs.com/skywang12345/p/io_26.html

3、http://baike.baidu.com/link?url=XqFXrey5USYJQ9kJVKufnL18QtobxJ6DRvYVfjUhXINC8Afctou3qKiN12ZPFSPUNLzyqMGa1ttl12zR7ZG-DA_hv7m3_MLmnSWNdYT6-re

四、联系本人

  为方便没有博客园账号的读者交流,特意建立一个企鹅群(纯公益,非利益相关),读者如果有对博文不明之处,欢迎加群交流:261746360,小杜比亚-博客园

偶遇RandomAccessFile的更多相关文章

  1. 文件随机读写专用类——RandomAccessFile

     RandomAccessFile类可以随机读取文件,但是在测试中并不好用;File类可以测试文件存不存在,不存在可以创建文件;FileWriter类可以对文件进行重写或者追加内容;FileReade ...

  2. [Java IO]01_File类和RandomAccessFile类

    File类 File类是java.io包中唯一对文件本身进行操作的类.它可以进行创建.删除文件等操作.   File类常用操作 (1)创建文件 可以使用 createNewFille() 创建一个新文 ...

  3. JAVASE02-Unit06: 文件操作——File 、 文件操作—— RandomAccessFile

    Unit06: 文件操作--File . 文件操作-- RandomAccessFile java.io.FileFile的每一个实例是用来表示文件系统中的一个文件或目录 package day06; ...

  4. Java RandomAccessFile用法

    RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须 ...

  5. Java: RandomAccessFile

    RandeomAccessFile虽然是java.io中的成员,但该类只继承了Object类,实现了DataOut, DataIn, Closeable等接口.此类的实例支持对文件的随机访问和读取.随 ...

  6. RAF(RandomAccessFile)类

    作用:读取文件 /** * */ package com.io.file; import java.io.File; import java.io.IOException; import java.i ...

  7. RandomAccessFile使用小结

    本文是基于Linux环境运行,读者阅读前需要具备一定Linux知识 RandomAccessFile是Java输入/输出流体系中功能最丰富的文件内容访问类,既可以读取文件内容,也可以向文件输出数据.与 ...

  8. RandomAccessFile拆分合并文件

    import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java. ...

  9. Java--使用多线程下载,断点续传技术原理(RandomAccessFile)

    一.基础知识 1.什么是线程?什么是进程?它们之间的关系? 可以参考之前的一篇文章:java核心知识点学习----并发和并行的区别,进程和线程的区别,如何创建线程和线程的四种状态,什么是线程计时器 简 ...

随机推荐

  1. [USACO1.5]数字三角形 Number Triangles

    题目描述 观察下面的数字金字塔. 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大.每一步可以走到左下方的点也可以到达右下方的点. 7 3 8 8 1 0 2 7 4 4 4 5 ...

  2. Docker 入坑教程笔记

    Docker 入坑教程笔记 视频网址B站:点这里 查询命令 man docker 简单启动和退出 docker run --name [容器名] -i -t ubuntu /bin/bash 交互启动 ...

  3. Linux下安装google拼音输入法

    首先安装fcitx,前几天看了很多在ubuntu上能够使用的输入法,有人推荐是搜狗输入法,毕竟是国产嘛,但是会有意外发生,比如说安装之后会产生输入的字符乱码,是一堆看不懂的东西,我就是因为遇到了,然后 ...

  4. JavaScript实现Tab切换

    在网页开发中,常常会遇见很多Tab切换,Tab切换增加网页浏览的舒适性,对于开发人员特别常见,本文使用JS实现tab切换效果,仅对学习中遇到的知识点做一个总结. 效果图如下:     实现思路: 1. ...

  5. 让图片在div盒子中水平垂直居中

    //调整多张图片,让图片水平垂直居中 function adjustImg(){ let imgDiv = document.getElementsByClassName("img" ...

  6. zookeeper相关知识与集群搭建

    Zookeeper Zookeeper相关概念 Zookeeper概述 Zookeeper是一个分布式协调服务的开源框架,主要用来解决分布式集群中应用系统的一致性问题. Zookeeper本质上是一个 ...

  7. 在Pycharm中导入第三方模块库(诸如:matplotlib、numpy等)

    在Pycharm中导入第三方模块库 一.打开pycharm: 二.点击菜单上的“file” -> “setting”: 三.步骤二完成后出现界面如下所示.选中你的项目(比如thisyan Pro ...

  8. 基于OMAPL:Linux3.3内核的编译

    基于OMAPL:Linux3.3内核的编译 OMAPL对应3个版本的linux源代码,分别是:Linux-3.3.Linux-2.6.37.Linux2.6.33,这里的差距在于Linux2,缺少SY ...

  9. Leecode刷题之旅-C语言/python-28.实现strstr()

    /* * @lc app=leetcode.cn id=28 lang=c * * [28] 实现strStr() * * https://leetcode-cn.com/problems/imple ...

  10. B -- POJ 1208 The Blocks Problem

    参考:https://blog.csdn.net/yxz8102/article/details/53098575 https://www.cnblogs.com/tanjuntao/p/867892 ...