RandomAccessFile 类封装了随机访问文件的功能,该类并非派生自InputStream或OutputStream类,而是实现了DataInput与DataOutput接口,这两这个接口还定义了基本的I/O方法。此外,RandomAccessFile还实现了AutoCloseable和Closeable接口。RandomAccessFile很特殊,因为支持定位需求,既可以定义文件中的文件指针。RandomAccessFile具有以下两个构造函数:
RandomAccessFile(File fileobj,String access)throws FileNotFoundException
RandomAccessFile(String filename,String access)throws FileNotFoundException
在第一种形式中,fileobj指定了作为File对象打开的文件。在第二种形式中,文件名称是通过filename传递的。对于这两种形式,access界定了允许的文件访问类型。如果access为“r”,就只能读文件,不能写文件;如果为“rw”就说明文件是以“读——写”模式打开的;如果为“rws”,就说明文件是针对“读-写”操作打开的,并且每次对文件中的数据或元数据的修改都会被立即写入物理设备中;如果为“rwd”就说明文件是针对读-写操作打开的,并且每次对文件数据的修改都会被立即写入到物理设备中。
seek()方法用于设置文件指针在文件中的当前位置,如下所示:
void seek(long newpos) throws IOException
其中newpos指定了新位置,以字节为单位指定文件指针距离文件开头的位置。在调用seek方法之后。下一次的读写操作将在新的位置发生。还有其他许多功能,在API中的
java.io包中均可查到,不再总结。
下面是本人的个人想法,就是利用传统方法和RandomAccessFile类 进行文件内容的读取和插入,如下所示。
import java.io.*; public class RandomAccessFileDemo { /*第一种传统读取文件内容的方式*/ static void readMethod(String file) throws IOException{ File f=new File(file);//普通方式进行文件读取,为了显示每个类用法,采用了字节转化为字符的方式进行了一一列举 FileInputStream f2=new FileInputStream(f); BufferedInputStream f3=new BufferedInputStream(f2); //每个InputStream对象都可以用BufferedInputStream来提高性能 InputStreamReader f4=new InputStreamReader(f3);//将字节转化为字符 try{ int c; while((c=f4.read())!=-1) System.out.print((char)c); }catch(IOException e){ System.out.println("I/O Exception: "+e); }finally{ try{ f2.close(); }catch(IOException e){ System.out.println("文件无法关闭"); } } } /*第二种读取文件内容的方式(利用RandomAccessFile类)*/ static void randomaccessRead(String file) throws IOException{ File f=new File(file);//利用RandomAccessFile类进行文件读取 try( RandomAccessFile rf=new RandomAccessFile(f,"r");){ int c; byte[] buffer=new byte[1024]; while((c=rf.read(buffer))!=-1){ System.out.print(new String(buffer,0,c)); } }catch(IOException e){ System.out.println("I/O Error: "+e); } } /*第一种在文件中插入内容的方法(利用RandomAccessFile类 移动文件指针)*/ static void randomInsertWrite(String file,int position,String str) throws IOException{ File f=new File(file); try(RandomAccessFile rw=new RandomAccessFile(f,"rwd")){ byte[] b=str.getBytes(); byte[] c=new byte[100]; rw.seek(position);//注意:从指针处写的内容会覆盖以前文件中指针后相等字节的内容 rw.read(c);//读取文件指针后的内容 rw.seek(position);//移动文件内容到插入位置 rw.write(b);//插入内容 rw.seek(position+b.length); //将文件指针移动到插入内容的后面 rw.write(c);//将原文件剩余内容补上 }catch(IOException e){ System.out.println("I/O Error: "+e); } } //第二种在文件中插入内容的方法(先将文件内容读入内存 经修改后再重新写入文件 static void randomInsertWrite2(String file,int position,String str) throws IOException{ File f=new File(file); try(RandomAccessFile rw=new RandomAccessFile(f,"rws")){ byte[] c=new byte[100]; rw.read(c); String c1=new String(c); String c2=c1.substring(0,position); String c3=c1.substring(position); String c4=c2+str+c3; byte[] b=c4.getBytes(); rw.seek(0); rw.write(b); }catch(IOException e){ System.out.println("I/O Error: "+e); } } public static void main(String[] args) throws IOException{ String file="c:file1.txt"; int pos=6; String str="(插入的内容sgxgsg)"; System.out.println("第一次插入前的内容为:"); readMethod(file); //传统方式进行读取 System.out.println(); randomaccessRead(file);//利用RandomAccessFile类进行读取 System.out.println(); randomInsertWrite(file,pos,str); //利用移动文件指针进行内容插入 System.out.println(); System.out.println("第一次插入后文件内容:"); readMethod(file); //插入后的文件内容 System.out.println("\n"); System.out.println("第二次插入前的内容为:"); readMethod(file); //传统方式进行读取 System.out.println(); randomaccessRead(file);//利用RandomAccessFile类进行读取 System.out.println(); randomInsertWrite2(file,pos,str); //利用移动文件指针进行内容插入 System.out.println(); System.out.println("第二次插入后文件内容:"); readMethod(file); //插入后的文件内容 System.out.println("\n"); } }