当前位置:首页 > 操作系统 > MacOs

偶遇RandomAccessFile

  本来在研究NIO,别人举的栗子里面,看到一个RandomAccessFile类,之前没见过,就去看了一下,现将相关内容记录如下

二、正文

  RandomAccessFile直接继承自Object,并且实现DataInput和DataOutput接口,它不属于InputStream和OutputStream类系的,并不是针对流的操作,它能在读取文件的时候前后移动,这个是和其他针对流操作的I/O类的本质区别。

  基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream粘起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样),它不支持只写文件。它支持对文件随机访问的读取和写入,即我们可以在指定的位置从文件读取/写入数据。

  平时,我们如果要往一个文件末尾追加一些数据,我们会将文件加载到内存,然后进行操作,但是如果文件本身非常大,比如好几G的量,那么普通的电脑承受不了,我们这时就可以使用RandomAccessFile,它无需将文件内容加载在内存,便可以在文件末尾追加内容。当然,有可能很多人会问,这个RandomAccessFile可以在文件指定位置插入数据吗?答案是:RandomAccessFile只能在指定位置修改数据,并不能插入数据(据我所知貌似没有哪个类支持在某个文件某个位置插入数据吧)。

  RandomAccessFile在读取等长数据的情况下也有优势。

  下面给出RandomAccessFile相关使用实例,先看下要操作的文件内容:

  偶遇RandomAccessFile - 文章图片

 

  

 

 

<span style="color: #008000">//</span><span style="color: #008000">实例一,从指定位置读取文件</span>
<span style="color: #0000ff">package</span><span style="color: #000000"> com.randomaccessfile.demo;

</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: #808080">@author</span><span style="color: #008000"> cyg
 * @date 2017-6-3 下午02:33:13
 * @description 随机读取文件的内容
 </span><span style="color: #008000">*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Demo1 {
    </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">文件内容:hello world!</span>
        RandomAccessFile raf = <span style="color: #0000ff">new</span> RandomAccessFile("C:UsersjackalcDesktopdemo.txt", "r"<span style="color: #000000">);
        System.out.println(</span>"在未指定位置之前,文件指针:"+<span style="color: #000000">raf.getFilePointer());
        raf.seek(</span>6);<span style="color: #008000">//</span><span style="color: #008000">指定文件指针位置,从0开始</span>
        System.out.println("在指定位置之后,文件指针:"+<span style="color: #000000">raf.getFilePointer());
        </span><span style="color: #0000ff">int</span> readLength = 0<span style="color: #000000">;
        </span><span style="color: #0000ff">byte</span> [] bytes = <span style="color: #0000ff">new</span> <span style="color: #0000ff">byte</span>[1024<span style="color: #000000">];
        </span><span style="color: #0000ff">while</span>((readLength=raf.read(bytes))>0<span style="color: #000000">){
            System.out.println(</span><span style="color: #0000ff">new</span> String(bytes,0<span style="color: #000000">,readLength));
        }
    }
}

</span><span style="color: #008000">//</span><span style="color: #008000">输出</span>
在未指定位置之前,文件指针:0<span style="color: #000000">
在指定位置之后,文件指针:</span>6<span style="color: #000000">
world</span>!
<span style="color: #008000">//</span><span style="color: #008000">实例二,文件末尾追加内容</span>
<span style="color: #0000ff">package</span><span style="color: #000000"> com.randomaccessfile.demo;

</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: #808080">@author</span><span style="color: #008000"> cyg
 * @date 2017-6-3 下午02:33:13
 * @description 文件末尾追加内容
 </span><span style="color: #008000">*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Demo2 {
    </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">文件内容:hello world!</span>
        RandomAccessFile raf = <span style="color: #0000ff">new</span> RandomAccessFile("C:UsersjackalcDesktopdemo.txt", "rw");<span style="color: #008000">//</span><span style="color: #008000">读写方式打开</span>
        raf.seek(raf.length());<span style="color: #008000">//</span><span style="color: #008000">将文件的指针移动到原先内容最后一个字节的后面</span>
        raf.write("最末尾追加的内容"<span style="color: #000000">.getBytes());
    }
}</span>

  实例二运行后,文件内容变更为:

  偶遇RandomAccessFile - 文章图片

 

 

 

 

 

 

 

<span style="color: #008000">//</span><span style="color: #008000">实例三,在文件指定位置修改文件</span>
<span style="color: #0000ff">package</span><span style="color: #000000"> com.randomaccessfile.demo;

</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: #808080">@author</span><span style="color: #008000"> cyg
 * @date 2017-6-3 下午02:33:13
 * @description 在文件指定位置修改文件
 </span><span style="color: #008000">*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Demo3 {
    </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">文件内容:hello world!</span>
        RandomAccessFile raf = <span style="color: #0000ff">new</span> RandomAccessFile("C:UsersjackalcDesktopdemo.txt", "rw");<span style="color: #008000">//</span><span style="color: #008000">读写方式打开</span>
        raf.seek(6);<span style="color: #008000">//</span><span style="color: #008000">"6"是“w”所在的位置</span>
        raf.write("我现在在指定的位置修改内容,我会覆盖从指定位置开始,和我等长的文件内容!"<span style="color: #000000">.getBytes());
    }
}</span>

  实例三运行之后,文件内容变更成这样:

偶遇RandomAccessFile - 文章图片

 

  

 

 

 

 

 

  如果想要在文件指定位置插入数据,而不是修改数据,要怎么操作呢?RandomAccessFile并没有提供这个方法,对于这个需求,我们可以将指定位置后面的内容先存储到临时文件里面,然后等内容插入完,我们再将临时文件的内容插入到刚刚插入的内容后面,贴一下别人的代码(原文见“三、连接”处):

<span style="color: #008000">//</span><span style="color: #008000">实例四,在文件指定位置插入内容</span>
<span style="color: #0000ff">package</span><span style="color: #000000"> com.randomaccessfile.demo;

</span><span style="color: #0000ff">import</span><span style="color: #000000"> java.io.File;
</span><span style="color: #0000ff">import</span><span style="color: #000000"> java.io.FileInputStream;
</span><span style="color: #0000ff">import</span><span style="color: #000000"> java.io.FileOutputStream;
</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: #808080">@author</span><span style="color: #008000"> cyg
 * @date 2017-6-3 下午02:33:13
 * @description 在文件指定位置插入内容
 </span><span style="color: #008000">*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Demo4 {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {
        </span><span style="color: #008000">//</span><span style="color: #008000">文件内容:hello world!</span>
        String path="C:UsersjackalcDesktopdemo.txt"<span style="color: #000000">;         
        insert(path, </span>6, "这是我需要插入的内容,不覆盖原先的内容"<span style="color: #000000">);  
    }  
    </span><span style="color: #008000">/**</span><span style="color: #008000"> 
     * 实现向指定位置 
     * 插入数据 
     * </span><span style="color: #808080">@param</span><span style="color: #008000"> fileName 文件名 
     * </span><span style="color: #808080">@param</span><span style="color: #008000"> points 指针位置 
     * </span><span style="color: #808080">@param</span><span style="color: #008000"> insertContent 插入内容 
     * *</span><span style="color: #008000">*/</span>  
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> insert(String fileName,<span style="color: #0000ff">long</span><span style="color: #000000"> points,String insertContent){  
        </span><span style="color: #0000ff">try</span><span style="color: #000000">{  
        File tmp</span>=File.createTempFile("tmp", <span style="color: #0000ff">null</span><span style="color: #000000">);  
        tmp.deleteOnExit();</span><span style="color: #008000">//</span><span style="color: #008000">在JVM退出时删除  </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: #008000">//</span><span style="color: #008000">创建一个临时文件夹来保存插入点后的数据  </span>
        FileOutputStream tmpOut=<span style="color: #0000ff">new</span><span style="color: #000000"> FileOutputStream(tmp);  
        FileInputStream tmpIn</span>=<span style="color: #0000ff">new</span><span style="color: #000000"> FileInputStream(tmp);  
        raf.seek(points);  
        </span><span style="color: #008000">/**</span><span style="color: #008000">将插入点后的内容读入临时文件夹*</span><span style="color: #008000">*/</span>  
          
        <span style="color: #0000ff">byte</span> [] buff=<span style="color: #0000ff">new</span> <span style="color: #0000ff">byte</span>[1024<span style="color: #000000">];  
        </span><span style="color: #008000">//</span><span style="color: #008000">用于保存临时读取的字节数  </span>
        <span style="color: #0000ff">int</span> hasRead=0<span style="color: #000000">;  
        </span><span style="color: #008000">//</span><span style="color: #008000">循环读取插入点后的内容  </span>
        <span style="color: #0000ff">while</span>((hasRead=raf.read(buff))>0<span style="color: #000000">){  
            </span><span style="color: #008000">//</span><span style="color: #008000"> 将读取的数据写入临时文件中  </span>
            tmpOut.write(buff, 0<span style="color: #000000">, hasRead);  
        }  
          
        </span><span style="color: #008000">//</span><span style="color: #008000">插入需要指定添加的数据  </span>
        raf.seek(points);<span style="color: #008000">//</span><span style="color: #008000">返回原来的插入处  
        </span><span style="color: #008000">//</span><span style="color: #008000">追加需要追加的内容  </span>
<span style="color: #000000">        raf.write(insertContent.getBytes());  
        </span><span style="color: #008000">//</span><span style="color: #008000">最后追加临时文件中的内容  </span>
        <span style="color: #0000ff">while</span>((hasRead=tmpIn.read(buff))>0<span style="color: #000000">){  
            raf.write(buff,</span>0<span style="color: #000000">,hasRead);  
        }  
        }</span><span style="color: #0000ff">catch</span><span style="color: #000000">(Exception e){  
            e.printStackTrace();  
        }  
    }  
}</span>

  实例四运行完之后,文件内容如下:

偶遇RandomAccessFile - 文章图片

 

 

 

 

 

 

 

 

 

三、链接

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

2、http://www.cnblogs.com/skywang12345/p/io_26.html

3、http://baike.baidu.com/link?url=XqFXrey5USYJQ9kJVKufnL18QtobxJ6DRvYVfjUhXINC8Afctou3qKiN12ZPFSPUNLzyqMGa1ttl12zR7ZG-DA_hv7m3_MLmnSWNdYT6-re

四、联系本人

  为方便没有博客园账号的读者交流,特意建立一个企鹅群(纯公益,非利益相关),读者如果有对博文不明之处,欢迎加群交流:261746360,小杜比亚-博客园

偶遇RandomAccessFile

标签:user   操作   hello   get   static   ges   指针   流操作   new   

本文系统来源:http://www.cnblogs.com/xdouby/p/6937434.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

相关教程推荐

其他课程推荐