- 浏览: 113816 次
- 性别:
- 来自: 成都
文章分类
最新评论
java中的RandomAccessFile的用法
RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。
RandomAccessFile不属于InputStream和OutputStream类系的。实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫不相干,甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写的。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。
基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream结合起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )、skipBytes()跳过多少字节数。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样)。它不支持只写文件。
只有RandomAccessFile才有seek搜寻方法,而这个方法也只适用于文件。BufferedInputStream有一个mark( )方法,你可以用它来设定标记(把结果保存在一个内部变量里),然后再调用reset( )返回这个位置,但是它的功能太弱了,而且也不怎么实用。
RandomAccessFile的绝大多数功能,但不是全部,已经被JDK 1.4的nio的"内存映射文件(memory-mapped files)"给取代了,你该考虑一下是不是用"内存映射文件"来代替RandomAccessFile了。
- importjava.io.IOException;
- importjava.io.RandomAccessFile;
- publicclassTestRandomAccessFile{
- publicstaticvoidmain(String[]args)throwsIOException{
- RandomAccessFilerf=newRandomAccessFile("rtest.dat","rw");
- for(inti=0;i<10;i++){
- //写入基本类型double数据
- rf.writeDouble(i*1.414);
- }
- rf.close();
- rf=newRandomAccessFile("rtest.dat","rw");
- //直接将文件指针移到第5个double数据后面
- rf.seek(5*8);
- //覆盖第6个double数据
- rf.writeDouble(47.0001);
- rf.close();
- rf=newRandomAccessFile("rtest.dat","r");
- for(inti=0;i<10;i++){
- System.out.println("Value"+i+":"+rf.readDouble());
- }
- rf.close();
- }
- }
import java.io.IOException;
import java.io.RandomAccessFile;
public class TestRandomAccessFile {
public static void main(String[] args) throws IOException {
RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");
for (int i = 0; i < 10; i++) {
//写入基本类型double数据
rf.writeDouble(i * 1.414);
}
rf.close();
rf = new RandomAccessFile("rtest.dat", "rw");
//直接将文件指针移到第5个double数据后面
rf.seek(5 * 8);
//覆盖第6个double数据
rf.writeDouble(47.0001);
rf.close();
rf = new RandomAccessFile("rtest.dat", "r");
for (int i = 0; i < 10; i++) {
System.out.println("Value " + i + ": " + rf.readDouble());
}
rf.close();
}
}
内存映射文件
内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问。这种解决办法能大大简化修改文件的代码。
fileChannel.map(FileChannel.MapMode mode, long position, long size)将此通道的文件区域直接映射到内存中。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。
MappedByteBuffer是ByteBuffer的子类,因此它具备了ByteBuffer的所有方法,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此之外,你还可以使用asCharBuffer( )之类的方法得到相应基本类型数据的缓冲视图后,可以方便的读写基本类型数据。
- importjava.io.RandomAccessFile;
- importjava.nio.MappedByteBuffer;
- importjava.nio.channels.FileChannel;
- publicclassLargeMappedFiles{
- staticintlength=0x8000000;//128Mb
- publicstaticvoidmain(String[]args)throwsException{
- //为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。
- FileChannelfc=newRandomAccessFile("test.dat","rw").getChannel();
- //注意,文件通道的可读可写要建立在文件流本身可读写的基础之上
- MappedByteBufferout=fc.map(FileChannel.MapMode.READ_WRITE,0,length);
- //写128M的内容
- for(inti=0;i<length;i++){
- out.put((byte)'x');
- }
- System.out.println("Finishedwriting");
- //读取文件中间6个字节内容
- for(inti=length/2;i<length/2+6;i++){
- System.out.print((char)out.get(i));
- }
- fc.close();
- }
- }
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class LargeMappedFiles {
static int length = 0x8000000; // 128 Mb
public static void main(String[] args) throws Exception {
// 为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。
FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();
//注意,文件通道的可读可写要建立在文件流本身可读写的基础之上
MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);
//写128M的内容
for (int i = 0; i < length; i++) {
out.put((byte) 'x');
}
System.out.println("Finished writing");
//读取文件中间6个字节内容
for (int i = length / 2; i < length / 2 + 6; i++) {
System.out.print((char) out.get(i));
}
fc.close();
}
}
尽管映射写似乎要用到FileOutputStream,但是映射文件中的所有输出必须使用RandomAccessFile,但如果只需要读时可以使用FileInputStream,写映射文件时一定要使用随机访问文件,可能写时要读的原因吧。
该程序创建了一个128Mb的文件,如果一次性读到内存可能导致内存溢出,但这里访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。注意,Java是调用操作系统的"文件映射机制"来提升性能的。
RandomAccessFile类的应用:
- /*
- *程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。
- */
- packagecom.lwj.demo;
- importjava.io.*;
- publicclassRandomAccessFileDemo{
- publicstaticvoidmain(String[]args)throwsException{
- RandomAccessFilefile=newRandomAccessFile("file","rw");
- //以下向file文件中写数据
- file.writeInt(20);//占4个字节
- file.writeDouble(8.236598);//占8个字节
- file.writeUTF("这是一个UTF字符串");//这个长度写在当前文件指针的前两个字节处,可用readShort()读取
- file.writeBoolean(true);//占1个字节
- file.writeShort(395);//占2个字节
- file.writeLong(2325451l);//占8个字节
- file.writeUTF("又是一个UTF字符串");
- file.writeFloat(35.5f);//占4个字节
- file.writeChar('a');//占2个字节
- file.seek(0);//把文件指针位置设置到文件起始处
- //以下从file文件中读数据,要注意文件指针的位置
- System.out.println("——————从file文件指定位置读数据——————");
- System.out.println(file.readInt());
- System.out.println(file.readDouble());
- System.out.println(file.readUTF());
- file.skipBytes(3);//将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。
- System.out.println(file.readLong());
- file.skipBytes(file.readShort());//跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。
- System.out.println(file.readFloat());
- //以下演示文件复制操作
- System.out.println("——————文件复制(从file到fileCopy)——————");
- file.seek(0);
- RandomAccessFilefileCopy=newRandomAccessFile("fileCopy","rw");
- intlen=(int)file.length();//取得文件长度(字节数)
- byte[]b=newbyte[len];
- file.readFully(b);
- fileCopy.write(b);
- System.out.println("复制完成!");
- }
- }
/*
* 程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。
*/
package com.lwj.demo;
import java.io.*;
public class RandomAccessFileDemo {
public static void main(String[] args) throws Exception {
RandomAccessFile file = new RandomAccessFile("file", "rw");
// 以下向file文件中写数据
file.writeInt(20);// 占4个字节
file.writeDouble(8.236598);// 占8个字节
file.writeUTF("这是一个UTF字符串");// 这个长度写在当前文件指针的前两个字节处,可用readShort()读取
file.writeBoolean(true);// 占1个字节
file.writeShort(395);// 占2个字节
file.writeLong(2325451l);// 占8个字节
file.writeUTF("又是一个UTF字符串");
file.writeFloat(35.5f);// 占4个字节
file.writeChar('a');// 占2个字节
file.seek(0);// 把文件指针位置设置到文件起始处
// 以下从file文件中读数据,要注意文件指针的位置
System.out.println("——————从file文件指定位置读数据——————");
System.out.println(file.readInt());
System.out.println(file.readDouble());
System.out.println(file.readUTF());
file.skipBytes(3);// 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。
System.out.println(file.readLong());
file.skipBytes(file.readShort()); // 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。
System.out.println(file.readFloat());
//以下演示文件复制操作
System.out.println("——————文件复制(从file到fileCopy)——————");
file.seek(0);
RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");
int len=(int)file.length();//取得文件长度(字节数)
byte[] b=new byte[len];
file.readFully(b);
fileCopy.write(b);
System.out.println("复制完成!");
}
}
RandomAccessFile 插入写示例:
- /**
- *
- *@paramskip跳过多少过字节进行插入数据
- *@paramstr要插入的字符串
- *@paramfileName文件路径
- */
- publicstaticvoidbeiju(longskip,Stringstr,StringfileName){
- try{
- RandomAccessFileraf=newRandomAccessFile(fileName,"rw");
- if(skip<0||skip>raf.length()){
- System.out.println("跳过字节数无效");
- return;
- }
- byte[]b=str.getBytes();
- raf.setLength(raf.length()+b.length);
- for(longi=raf.length()-1;i>b.length+skip-1;i--){
- raf.seek(i-b.length);
- bytetemp=raf.readByte();
- raf.seek(i);
- raf.writeByte(temp);
- }
- raf.seek(skip);
- raf.write(b);
- raf.close();
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
/**
*
* @param skip 跳过多少过字节进行插入数据
* @param str 要插入的字符串
* @param fileName 文件路径
*/
public static void beiju(long skip, String str, String fileName){
try {
RandomAccessFile raf = new RandomAccessFile(fileName,"rw");
if(skip < 0 || skip > raf.length()){
System.out.println("跳过字节数无效");
return;
}
byte[] b = str.getBytes();
raf.setLength(raf.length() + b.length);
for(long i = raf.length() - 1; i > b.length + skip - 1; i--){
raf.seek(i - b.length);
byte temp = raf.readByte();
raf.seek(i);
raf.writeByte(temp);
}
raf.seek(skip);
raf.write(b);
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
利用RandomAccessFile实现文件的多线程下载,即多线程下载一个文件时,将文件分成几块,每块用不同的线程进行下载。下面是一个利用多线程在写文件时的例子,其中预先分配文件所需要的空间,然后在所分配的空间中进行分块,然后写入:
- importjava.io.FileNotFoundException;
- importjava.io.IOException;
- importjava.io.RandomAccessFile;
- /**
- *测试利用多线程进行文件的写操作
- */
- publicclassTest{
- publicstaticvoidmain(String[]args)throwsException{
- //预分配文件所占的磁盘空间,磁盘中会创建一个指定大小的文件
- RandomAccessFileraf=newRandomAccessFile("D://abc.txt","rw");
- raf.setLength(1024*1024);//预分配1M的文件空间
- raf.close();
- //所要写入的文件内容
- Strings1="第一个字符串";
- Strings2="第二个字符串";
- Strings3="第三个字符串";
- Strings4="第四个字符串";
- Strings5="第五个字符串";
- //利用多线程同时写入一个文件
- newFileWriteThread(1024*1,s1.getBytes()).start();//从文件的1024字节之后开始写入数据
- newFileWriteThread(1024*2,s2.getBytes()).start();//从文件的2048字节之后开始写入数据
- newFileWriteThread(1024*3,s3.getBytes()).start();//从文件的3072字节之后开始写入数据
- newFileWriteThread(1024*4,s4.getBytes()).start();//从文件的4096字节之后开始写入数据
- newFileWriteThread(1024*5,s5.getBytes()).start();//从文件的5120字节之后开始写入数据
- }
- //利用线程在文件的指定位置写入指定数据
- staticclassFileWriteThreadextendsThread{
- privateintskip;
- privatebyte[]content;
- publicFileWriteThread(intskip,byte[]content){
- this.skip=skip;
- this.content=content;
- }
- publicvoidrun(){
- RandomAccessFileraf=null;
- try{
- raf=newRandomAccessFile("D://abc.txt","rw");
- raf.seek(skip);
- raf.write(content);
- }catch(FileNotFoundExceptione){
- e.printStackTrace();
- }catch(IOExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }finally{
- try{
- raf.close();
- }catch(Exceptione){
- }
- }
- }
- }
- }
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 测试利用多线程进行文件的写操作
*/
public class Test {
public static void main(String[] args) throws Exception {
// 预分配文件所占的磁盘空间,磁盘中会创建一个指定大小的文件
RandomAccessFile raf = new RandomAccessFile("D://abc.txt", "rw");
raf.setLength(1024*1024); // 预分配 1M 的文件空间
raf.close();
// 所要写入的文件内容
String s1 = "第一个字符串";
String s2 = "第二个字符串";
String s3 = "第三个字符串";
String s4 = "第四个字符串";
String s5 = "第五个字符串";
// 利用多线程同时写入一个文件
new FileWriteThread(1024*1,s1.getBytes()).start(); // 从文件的1024字节之后开始写入数据
new FileWriteThread(1024*2,s2.getBytes()).start(); // 从文件的2048字节之后开始写入数据
new FileWriteThread(1024*3,s3.getBytes()).start(); // 从文件的3072字节之后开始写入数据
new FileWriteThread(1024*4,s4.getBytes()).start(); // 从文件的4096字节之后开始写入数据
new FileWriteThread(1024*5,s5.getBytes()).start(); // 从文件的5120字节之后开始写入数据
}
// 利用线程在文件的指定位置写入指定数据
static class FileWriteThread extends Thread{
private int skip;
private byte[] content;
public FileWriteThread(int skip,byte[] content){
this.skip = skip;
this.content = content;
}
public void run(){
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile("D://abc.txt", "rw");
raf.seek(skip);
raf.write(content);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
raf.close();
} catch (Exception e) {
}
}
}
}
}
相关推荐
在本示例中,提供的压缩包可能包含一个`java`源代码文件,演示了如何使用`RandomAccessFile`进行文件读写操作,以及一个编译后的`class`文件,这是运行Java程序的字节码文件。通过查看源代码,我们可以学习到`...
Java中的`RandomAccessFile`是一个强大的类,用于对文件进行随机访问读写。与传统的`InputStream`和`OutputStream`不同,`RandomAccessFile`允许你在文件的任意位置直接读写数据,而不仅仅是从文件的开头顺序读取。...
在实际应用中,我们还需要注意文件的关闭操作,确保使用完`RandomAccessFile`后调用`close()`方法,以释放系统资源并防止数据丢失。 `Raf.txt`可能是示例代码或关于`RandomAccessFile`使用的说明文本。在阅读这个...
4. 在insert方法中,首先创建一个临时文件,并在程序退出时自动删除这个文件。这一步是为了防止修改原文件内容时可能出现的意外情况。 5. 接着创建一个RandomAccessFile实例,并以读写模式打开目标文件。如果文件不...
Java中的`RandomAccessFile`类是一个强大的文件操作工具,它允许程序员以随机访问模式读取和写入文件。与标准的`FileInputStream`和`FileOutputStream`不同,`RandomAccessFile`不仅支持顺序读写,还能直接跳转到...
综上所述,使用`RandomAccessFile`向文件中写入中文时,建议采用`write(String.getBytes())`方法,并确保指定了正确的编码方式。这样不仅能避免乱码问题,还能确保文件内容的正确性。此外,还需要注意选择合适的编码...
下面将详细介绍`RandomAccessFile`的用法、特性以及一些关键方法。 1. **创建RandomAccessFile对象** 使用`RandomAccessFile`的第一步是创建一个实例,通常需要提供文件路径和访问模式。访问模式可以是"r"(只读)...
RandomAccessFile类是Java I/O库中的一个重要组件,它提供了对文件进行随机访问的能力,这意味着你可以直接跳到文件的任意位置进行读写操作,而不仅仅局限于从头到尾的顺序访问。这个类非常适合处理大数据量的文件,...
在学习Java基础的过程中,理解并掌握`RandomAccessFile`的用法对于提升编程技能和解决实际问题具有重要意义。通过观看"Java基础第16天-01.RandomAccessFile.avi"的视频教程,你将能够更深入地了解和运用这一特性。
Java的`RandomAccessFile`类是Java I/O流体系中的一种特殊类型,它允许程序员以随机访问模式读取和写入文件。与传统的输入/输出流不同,`RandomAccessFile`可以直接定位到文件的任意位置进行读写操作,这对于处理...
实际上,除了实现DataInput和 DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫不相干,甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是
Java 使用 RandomAccessFile 类基于指针读写文件实例代码 Java 中的 RandomAccessFile 类是一种基于指针操作的文件读写方式,能够实现对文件的随机访问。该类不同于其他许多基于流方式读写文件的类,它直接继承自 ...
Java中IO流 RandomAccessFile类实例详解 Java中的IO流 ...Java中的IO流 RandomAccessFile类实例详解是一个重要的知识点,掌握RandomAccessFile类的使用方法和相关技术细节,对于Java开发者来说非常重要。
### 使用RandomAccessFile流将一个文本文件读出并写入到另一个文件中的知识点解析 在Java编程语言中,`RandomAccessFile`类提供了一种非常灵活的方式来读取和写入文件。它支持随机访问,意味着我们可以直接跳转到...
在Java编程中,`RandomAccessFile` 类提供了一种方式来处理文件中的数据,允许程序随机访问文件的任何部分。但在处理中文或其他非ASCII字符时,可能会遇到乱码问题。这是因为不同编码方式对字符的表示方式不同,如果...
Java RandomAccessFile 是 Java 中的一个文件处理类,提供了随机访问文件的能力,支持读写文件的任意位置。下面是 Java RandomAccessFile 基本文件操作示例的知识点总结: 一、 RandomAccessFile 简介 ...
`RandomAccessFile`是Java中的一个类,位于`java.io`包中,它提供了对文件进行读写的能力,并且可以随机地定位到文件中的任何位置进行数据的读取或写入,这使得在处理大型文件时更为灵活高效。与`FileInputStream`和...
在Java编程语言中,`RandomAccessFile`是一个强大的类,用于对文件进行随机访问和读写操作。这个类提供了一种高效的方式,让我们能够在文件的任何位置读取或写入数据,而不仅仅是从文件的开头顺序读取。下面将详细...
在上面的代码中,我们使用了`FileInputStream`、`FileOutputStream`和`RandomAccessFile`类来实现IO操作。 知识点5:Java中的异常处理 在Java中,异常处理是通过使用`try-catch`语句来实现的。在上面的代码中,...
在本项目"Java+Access实现简易通讯录"中,我们主要关注的是如何使用Java编程语言与Microsoft Access数据库进行交互,以构建一个简单的通讯录系统。这个系统具备基本的增、删、改联系人信息的功能,适合初学者了解...