<span style="color: #0000ff;">import</span><span style="color: #000000;"> java.io.IOException;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.io.RandomAccessFile;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> TestRandomAccessFile {
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main(String[] args) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> IOException {
RandomAccessFile rf </span>= <span style="color: #0000ff;">new</span> RandomAccessFile("rtest.dat", "rw"<span style="color: #000000;">);
</span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < 10; i++<span style="color: #000000;">) {
</span><span style="color: #008000;">//</span><span style="color: #008000;">写入基本类型double数据</span>
rf.writeDouble(i * 1.414<span style="color: #000000;">);
}
rf.close();
rf </span>= <span style="color: #0000ff;">new</span> RandomAccessFile("rtest.dat", "rw"<span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;">直接将文件指针移到第5个double数据后面</span>
rf.seek(5 * 8<span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;">覆盖第6个double数据</span>
rf.writeDouble(47.0001<span style="color: #000000;">);
rf.close();
rf </span>= <span style="color: #0000ff;">new</span> RandomAccessFile("rtest.dat", "r"<span style="color: #000000;">);
</span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < 10; i++<span style="color: #000000;">) {
System.out.println(</span>"Value " + i + ": " +<span style="color: #000000;"> rf.readDouble());
}
rf.close();
}
}</span>
内存映射文件
内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问。这种解决办法能大大简化修改文件的代码。 fileChannel.map(FileChannel.MapMode mode, long position, long size)将此通道的文件区域直接映射到内存中。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。
MappedByteBuffer是ByteBuffer的子类,因此它具备了ByteBuffer的所有方法,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此之外,你还可以使用asCharBuffer( )之类的方法得到相应基本类型数据的缓冲视图后,可以方便的读写基本类型数据。
<span style="color: #0000ff;">import</span><span style="color: #000000;"> java.io.RandomAccessFile;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.nio.MappedByteBuffer;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.nio.channels.FileChannel;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> LargeMappedFiles {
</span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span> length = 0x8000000; <span style="color: #008000;">//</span><span style="color: #008000;"> 128 Mb</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main(String[] args) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> Exception {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。</span>
FileChannel fc = <span style="color: #0000ff;">new</span> RandomAccessFile("test.dat", "rw"<span style="color: #000000;">).getChannel();
</span><span style="color: #008000;">//</span><span style="color: #008000;">注意,文件通道的可读可写要建立在文件流本身可读写的基础之上</span>
MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0<span style="color: #000000;">, length);
</span><span style="color: #008000;">//</span><span style="color: #008000;">写128M的内容</span>
<span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < length; i++<span style="color: #000000;">) {
out.put((</span><span style="color: #0000ff;">byte</span>) ‘x‘<span style="color: #000000;">);
}
System.out.println(</span>"Finished writing"<span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;">读取文件中间6个字节内容</span>
<span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = length / 2; i < length / 2 + 6; i++<span style="color: #000000;">) {
System.out.print((</span><span style="color: #0000ff;">char</span><span style="color: #000000;">) out.get(i));
}
fc.close();
}
}</span>
尽管映射写似乎要用到FileOutputStream,但是映射文件中的所有输出 必须使用RandomAccessFile,但如果只需要读时可以使用FileInputStream,写映射文件时一定要使用随机访问文件,可能写时要读的原因吧。
该程序创建了一个128Mb的文件,如果一次性读到内存可能导致内存溢出,但这里访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。注意,Java是调用操作系统的"文件映射机制"来提升性能的。
RandomAccessFile类的应用:
<span style="color: #008000;">/*</span><span style="color: #008000;">
* 程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">package</span><span style="color: #000000;"> com.lwj.demo;
</span><span style="color: #0000ff;">import</span> java.io.*<span style="color: #000000;">;
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> RandomAccessFileDemo {
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main(String[] args) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> Exception {
RandomAccessFile file </span>= <span style="color: #0000ff;">new</span> RandomAccessFile("file", "rw"<span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 以下向file文件中写数据</span>
file.writeInt(20);<span style="color: #008000;">//</span><span style="color: #008000;"> 占4个字节</span>
file.writeDouble(8.236598);<span style="color: #008000;">//</span><span style="color: #008000;"> 占8个字节</span>
file.writeUTF("这是一个UTF字符串");<span style="color: #008000;">//</span><span style="color: #008000;"> 这个长度写在当前文件指针的前两个字节处,可用readShort()读取</span>
file.writeBoolean(<span style="color: #0000ff;">true</span>);<span style="color: #008000;">//</span><span style="color: #008000;"> 占1个字节</span>
file.writeShort(395);<span style="color: #008000;">//</span><span style="color: #008000;"> 占2个字节</span>
file.writeLong(2325451l);<span style="color: #008000;">//</span><span style="color: #008000;"> 占8个字节</span>
file.writeUTF("又是一个UTF字符串"<span style="color: #000000;">);
file.writeFloat(</span>35.5f);<span style="color: #008000;">//</span><span style="color: #008000;"> 占4个字节</span>
file.writeChar(‘a‘);<span style="color: #008000;">//</span><span style="color: #008000;"> 占2个字节</span>
<span style="color: #000000;">
file.seek(</span>0);<span style="color: #008000;">//</span><span style="color: #008000;"> 把文件指针位置设置到文件起始处
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 以下从file文件中读数据,要注意文件指针的位置</span>
System.out.println("——————从file文件指定位置读数据——————"<span style="color: #000000;">);
System.out.println(file.readInt());
System.out.println(file.readDouble());
System.out.println(file.readUTF());
file.skipBytes(</span>3);<span style="color: #008000;">//</span><span style="color: #008000;"> 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。</span>
<span style="color: #000000;"> System.out.println(file.readLong());
file.skipBytes(file.readShort()); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。</span>
<span style="color: #000000;"> System.out.println(file.readFloat());
</span><span style="color: #008000;">//</span><span style="color: #008000;">以下演示文件复制操作</span>
System.out.println("——————文件复制(从file到fileCopy)——————"<span style="color: #000000;">);
file.seek(</span>0<span style="color: #000000;">);
RandomAccessFile fileCopy</span>=<span style="color: #0000ff;">new</span> RandomAccessFile("fileCopy","rw"<span style="color: #000000;">);
</span><span style="color: #0000ff;">int</span> len=(<span style="color: #0000ff;">int</span>)file.length();<span style="color: #008000;">//</span><span style="color: #008000;">取得文件长度(字节数)</span>
<span style="color: #0000ff;">byte</span>[] b=<span style="color: #0000ff;">new</span> <span style="color: #0000ff;">byte</span><span style="color: #000000;">[len];
file.readFully(b);
fileCopy.write(b);
System.out.println(</span>"复制完成!"<span style="color: #000000;">);
}
}</span>
RandomAccessFile 插入写示例:
<span style="color: #008000;">/**</span><span style="color: #008000;">
*
* </span><span style="color: #808080;">@param</span><span style="color: #008000;"> skip 跳过多少过字节进行插入数据
* </span><span style="color: #808080;">@param</span><span style="color: #008000;"> str 要插入的字符串
* </span><span style="color: #808080;">@param</span><span style="color: #008000;"> fileName 文件路径
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> beiju(<span style="color: #0000ff;">long</span><span style="color: #000000;"> skip, String str, String fileName){
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
RandomAccessFile raf </span>= <span style="color: #0000ff;">new</span> RandomAccessFile(fileName,"rw"<span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span>(skip < 0 || skip ><span style="color: #000000;"> raf.length()){
System.out.println(</span>"跳过字节数无效"<span style="color: #000000;">);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;
}
</span><span style="color: #0000ff;">byte</span>[] b =<span style="color: #000000;"> str.getBytes();
raf.setLength(raf.length() </span>+<span style="color: #000000;"> b.length);
</span><span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">long</span> i = raf.length() - 1; i > b.length + skip - 1; i--<span style="color: #000000;">){
raf.seek(i </span>-<span style="color: #000000;"> b.length);
</span><span style="color: #0000ff;">byte</span> temp =<span style="color: #000000;"> raf.readByte();
raf.seek(i);
raf.writeByte(temp);
}
raf.seek(skip);
raf.write(b);
raf.close();
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
e.printStackTrace();
}
}</span>
利用RandomAccessFile实现文件的多线程下载,即多线程下载一个文件时,将文件分成几块,每块用不同的线程进行下载。下面是一个利用多线程在写文件时的例子,其中预先分配文件所需要的空间,然后在所分配的空间中进行分块,然后写入:
<span style="color: #0000ff;">import</span><span style="color: #000000;"> java.io.FileNotFoundException;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.io.IOException;
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> java.io.RandomAccessFile;
</span><span style="color: #008000;">/**</span><span style="color: #008000;">
* 测试利用多线程进行文件的写操作
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Test {
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main(String[] args) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> Exception {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 预分配文件所占的磁盘空间,磁盘中会创建一个指定大小的文件</span>
RandomAccessFile raf = <span style="color: #0000ff;">new</span> RandomAccessFile("D://abc.txt", "rw"<span style="color: #000000;">);
raf.setLength(</span>1024*1024); <span style="color: #008000;">//</span><span style="color: #008000;"> 预分配 1M 的文件空间</span>
<span style="color: #000000;"> raf.close();
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 所要写入的文件内容</span>
String s1 = "第一个字符串"<span style="color: #000000;">;
String s2 </span>= "第二个字符串"<span style="color: #000000;">;
String s3 </span>= "第三个字符串"<span style="color: #000000;">;
String s4 </span>= "第四个字符串"<span style="color: #000000;">;
String s5 </span>= "第五个字符串"<span style="color: #000000;">;
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 利用多线程同时写入一个文件</span>
<span style="color: #0000ff;">new</span> FileWriteThread(1024*1,s1.getBytes()).start(); <span style="color: #008000;">//</span><span style="color: #008000;"> 从文件的1024字节之后开始写入数据</span>
<span style="color: #0000ff;">new</span> FileWriteThread(1024*2,s2.getBytes()).start(); <span style="color: #008000;">//</span><span style="color: #008000;"> 从文件的2048字节之后开始写入数据</span>
<span style="color: #0000ff;">new</span> FileWriteThread(1024*3,s3.getBytes()).start(); <span style="color: #008000;">//</span><span style="color: #008000;"> 从文件的3072字节之后开始写入数据</span>
<span style="color: #0000ff;">new</span> FileWriteThread(1024*4,s4.getBytes()).start(); <span style="color: #008000;">//</span><span style="color: #008000;"> 从文件的4096字节之后开始写入数据</span>
<span style="color: #0000ff;">new</span> FileWriteThread(1024*5,s5.getBytes()).start(); <span style="color: #008000;">//</span><span style="color: #008000;"> 从文件的5120字节之后开始写入数据</span>
<span style="color: #000000;"> }
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 利用线程在文件的指定位置写入指定数据</span>
<span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span> FileWriteThread <span style="color: #0000ff;">extends</span><span style="color: #000000;"> Thread{
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> skip;
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">byte</span><span style="color: #000000;">[] content;
</span><span style="color: #0000ff;">public</span> FileWriteThread(<span style="color: #0000ff;">int</span> skip,<span style="color: #0000ff;">byte</span><span style="color: #000000;">[] content){
</span><span style="color: #0000ff;">this</span>.skip =<span style="color: #000000;"> skip;
</span><span style="color: #0000ff;">this</span>.content =<span style="color: #000000;"> content;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run(){
RandomAccessFile raf </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
raf </span>= <span style="color: #0000ff;">new</span> RandomAccessFile("D://abc.txt", "rw"<span style="color: #000000;">);
raf.seek(skip);
raf.write(content);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (FileNotFoundException e) {
e.printStackTrace();
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (IOException e) {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated catch block</span>
<span style="color: #000000;"> e.printStackTrace();
} </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
raf.close();
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
}
}
}
}
}</span>
Java RandomAccessFile用法 【转】
标签:
本文系统来源:http://www.cnblogs.com/disneyland/p/4556473.html
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!