现有如下的一个需求,向已存在1G数据的txt文本里末尾追加一行文字,内容如下“Lucene是一款非常优秀的全文检索库”。可能大多数朋友会觉得这个需求很easy,说实话,确实easy,然后XXX君开始实现了,直接使用Java中的流读取了txt文本里原来所有的数据转成字符串后,然后拼接了“Lucene是一款非常优秀的全文检索库”,又写回文本里了,至此,大功告成。后来需求改了,向5G数据的txt文本里追加了,结果XXX君傻了,他内存只有4G,如果强制读取所有的数据并追加,会报内存溢出的异常。

其实上面的需求很简单,如果我们使用JAVA IO体系中的RandomAccessFile类来完成的话,可以实现零内存追加。其实这就是支持任意位置读写类的强大之处。

RandomAccessFile是Java中输入,输出流体系中功能最丰富的文件内容访问类,它提供很多方法来操作文件,包括读写支持,与普通的IO流相比,它最大的特别之处就是支持任意访问的方式,程序可以直接跳到任意地方来读写数据。

如果我们只希望访问文件的部分内容,而不是把文件从头读到尾,使用RandomAccessFile将会带来更简洁的代码以及更好的性能。

下面来看下RandomAccessFile类中比较重要的2个方法,其他的和普通IO类似,在这里,就不详细说明了。

方法名 作用
getFilePointer() 返回文件记录指针的当前位置
seek(long pos) 将文件记录指针定位到pos的位置

功能one,读取任意位置的数据,代码如下|

/**
* 读的方法
* @param path 文件路径
* @param pointe 指针位置
* **/
public static void randomRed(String path,int pointe){
try{
//RandomAccessFile raf=new RandomAccessFile(new File("D:\\3\\test.txt"), "r");
/**
* model各个参数详解
* r 代表以只读方式打开指定文件
* rw 以读写方式打开指定文件
* rws 读写方式打开,并对内容或元数据都同步写入底层存储设备
* rwd 读写方式打开,对文件内容的更新同步更新至底层存储设备
*
* **/
RandomAccessFile raf=new RandomAccessFile(path, "r");
//获取RandomAccessFile对象文件指针的位置,初始位置是0
System.out.println("RandomAccessFile文件指针的初始位置:"+raf.getFilePointer());
raf.seek(pointe);//移动文件指针位置
byte[] buff=new byte[1024];
//用于保存实际读取的字节数
int hasRead=0;
//循环读取
while((hasRead=raf.read(buff))>0){
//打印读取的内容,并将字节转为字符串输入
System.out.println(new String(buff,0,hasRead)); } }catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
String path="D:\\3\\test.txt";
int seekPointer=20;
randomRed(path,seekPointer);//读取的方法
//randomWrite(path);//追加写的方法
//insert(path, 33, "\nlucene是一个优秀的全文检索库");
}
RandomAccessFile文件指针的初始位置:0
is a teacher
hadoop is perfect

功能two,追加数据,代码如下

/**
* 追加方式
* 写的方法
* @param path 文件路径
* ***/
public static void randomWrite(String path){
try{
/**以读写的方式建立一个RandomAccessFile对象**/
RandomAccessFile raf=new RandomAccessFile(path, "rw"); //将记录指针移动到文件最后
raf.seek(raf.length());
raf.write("我是追加的 \r\n".getBytes()); }catch(Exception e){
e.printStackTrace();
} }
public static void main(String[] args) {
String path="D:\\3\\test.txt";
//int seekPointer=20;
// randomRed(path,seekPointer);//读取的方法
randomWrite(path);//追加写的方法
//insert(path, 33, "\nlucene是一个优秀的全文检索库");
}

功能three,任意位置插入数据,代码如下

/**
* 实现向指定位置
* 插入数据
* @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();
}
}
public static void main(String[] args) {
String path="D:\\3\\test.txt";
//int seekPointer=20;
// randomRed(path,seekPointer);//读取的方法
// randomWrite(path);//追加写的方法
insert(path, 33, "\nlucene是一个优秀的全文检索库");
}

至此,RandomAccessFile类的几个功能,散仙在代码中已给出实现了,现在回到本文开始前的提的那个需求,用RandomAccessFile类就可以轻而易举的完成了,另外需要注意的是,向指定位置插入数据,是散仙自己改造的功能,RandomAccessFile并不直接支持,需要新建一个缓冲区临时空间,存数据,然后在写,因为一旦数据量上了级别,在任意位置插入数据,是很耗内存的,这个也就是为什么hadoop的HDFS文件系统,只支持append的方式,而没有提供修改的操作。

另外我们可以用RandomAccessFile这个类,来实现一个多线程断点下载的功能,用过下载工具的朋友们都知道,下载前都会建立两个临时文件,一个是与被下载文件大小相同的空文件,另一个是记录文件指针的位置文件,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会继续从上一次的地方下载,从而实现断点下载或上传的功能,有兴趣的朋友们可以自己实现下。

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

Java IO的RandomAccessFile的使用(转)的更多相关文章

  1. Java—IO流 RandomAccessFile类

    RandomAccessFile java提供的对文件内容的访问,既可以读文件,也可以写文件. 支持随机访问文件,可以访问文件的任意位置. java文件模型,在硬盘上的文件是byte byte byt ...

  2. Java IO 之 RandomAccessFile 操作文件内容

    RandomAccessFile类实现对文件内容的随机读写 文件内容的随机操作,重难点在于字符操作,具体查看API package org.zln.io.file; import java.io.IO ...

  3. Java IO学习--RandomAccessFile

    1.什么是 随机访问文件流 RandomAccessFile 这个类在很多资料上翻译成中文都是:随机访问文件,在中文里,随机是具有不确定的含义,指一会访问这里,一会访问那里的意思.如果以这种语义来解释 ...

  4. Java IO(二)--RandomAccessFile基本使用

    RandomAccessFile: 翻译过来就是任意修改文件,可以从文件的任意位置进行修改,迅雷的下载就是通过多个线程同时读取下载文件.例如,把一个文件分为四 部分,四个线程同时下载,最后进行内容拼接 ...

  5. Java IO系统--RandomAccessFile

    RandomAccessFile 实现了DataOutput接口和DataInput接口.父类是Object,不继承任何的InputStream和OutStram. public class Rand ...

  6. java io系列26之 RandomAccessFile

    本文主要介绍 RandomAccessFile. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_26.html 更多内容请参考:java io系列0 ...

  7. Java IO流学习

    Java IO流学习 Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是 ...

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

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

  9. Java IO RandomAccessFile 任意位置读/写

    随机读写类 RandomAccessFile的唯一父类是Object,与其他流父类不同.是用来访问那些保存数据记录的文件的,这样你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必 ...

随机推荐

  1. Go by Example

    Go by Example Go is an open source programming language designed for building simple, fast, and reli ...

  2. Java开发环境的基本设置

    作为Java的刚開始学习的人,不知道其它的刚開始学习的人有没有和我一样的感受:用Java开发须要配置这么复杂 的环境.太难了.第一次配置时,一团混乱.Oracle监听服务打不开了,PLSql连接不上O ...

  3. oracle 11g impdp时 报ORA-12899(转)

    源库ZHS16BGK,汉字在数据库存放的时候占用两个字节 目标库UTF8,汉字在数据库里存放的时候占用三个字节 由于字符集不同,导致现在数据库impdp的时候有些表的字段长度不够,出现ORA-1289 ...

  4. substance的使用示例(转)

    可以使用substance改变界面的皮肤和主题,让Java制作的界面“炫”起来 . 可以下载substance.jar文件 在代码中你可以用: static { try { try { UIManag ...

  5. 【HTML5游戏开发小技巧】RPG情形对话中,令文本逐琢夸出

    从前用JAVAscript完成过令文本逐琢夸出的效果,明天嗡炒用html5中的canvas完成一下.canvas里的内容可没有像<p>那样好操做,起首,您需求懂得一些html5的API才气 ...

  6. msyql在查询字段中的所有记录,不重复

    mysql> select * from a ;  +----+------+--------------+ | id | name | descri       | +----+------+ ...

  7. bzoj1001/BJOI2006 灰太狼抓到的兔子

    1001: [BeiJing2006]狼抓兔子(id=1001">传送门) 图论新知识..没学过.. 平面图最小割等于对偶图的最短路 详见课件:http://wenku.baidu.c ...

  8. CSDN挑战编程——《金色十月线上编程比赛第二题:解密》

    金色十月线上编程比赛第二题:解密 题目详情: 小强是一名学生, 同一时候他也是一个黑客. 考试结束后不久.他吃惊的发现自己的高等数学科目竟然挂了,于是他果断入侵了学校教务部站点. 在入侵的过程中.他发 ...

  9. 使用JSP实现商场购物车模块

    这些日子,学习JSP,只要找到一个小模块来试试你的手: 这里是实现车模块结果页面截图: 图1. 产品显示页面 通过此页面进行产品选择.增加到购物车 图2 .购物车页面 图3 . 商品数量设置 好了,先 ...

  10. Acdreamoj1115(数学思维称号)

    意甲冠军:1,3是完美的数,假定a,b是完美的数,然后,2+a*b+2*a+2*b,结论认为,n无论是完美的数字. 解法:開始仅仅看出来2+a*b+2*a+2*b=(a+2)*(b+2)-2,没推出很 ...