现有如下的一个需求,向已存在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. Context Switch and System Call

    How many Context Switches is “normal”? This depends very much on the type of application you run. If ...

  2. Javascript Base64编码与解码

    原文:[转]Javascript Base64编码与解码 <html> <head> <META HTTP-EQUIV="MSThemeCompatible&q ...

  3. cocos2dx移植android平台

    本人这几天一直都没有跟新自己的网站内容,问我干什么去了,当然是做这篇文章做的事了,说起这个移植来真是麻烦啊,网上试验了各种方法,都不知道谁对谁错啊.不过经过本人这三天的研究最后终于成功了,为了让大家少 ...

  4. Lucene 实例教程(四)之检索方法总结

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本人声明.否则将追究法律责任. 作者: 永恒の_☆ 地址: http://blog.csdn.net/chenghui031 ...

  5. Android SDK 5.0 这个语句带来折腾 - 生命在于折腾!

    Android SDK 5.0  带来的这番折腾 - 生命在于折腾! 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一 ...

  6. Codeforces 432E Square Tiling(结构体+贪婪)

    题目连接:Codeforces 432E Square Tiling 题目大意:给出一个n∗m的矩阵,要求对该矩阵进行上色,用大写字母,可是每次上色的区域必须是正方形,不求相邻的上色区域不能有同样的颜 ...

  7. Eclipse正确导入第三方project

    前言 昨晚,在不同的Android做出最终的在线测试时间,在其他平台上正常升级的提示突然报告出来"java.lang.NoClassDefFoundError"误.拉什adb lo ...

  8. sublime配置攻略

    大家好,今天给大家分享的编辑器:sublime text2     我用过非常多编辑器, EditPlus.EmEditor.Notepad++.Notepad2.UltraEdit.Editra.V ...

  9. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  10. C语言知识汇总

    1. strlen与sizeof差异问题: 以下程序的输出 #include <stdio.h> void main() { char * ptr="hello"; c ...