二. 存在意义
1、是JAVA I/O流体系中功能最丰富的文件内容访问类,它提供了众多方法来访问文件内容。
2、由于可以自由访问文件的任意位置,所以如果需要访问文件的部分内容,RandomAccessFile将是更好的选择。
3、可以用来访问保存数据记录的文件,文件的记录的大小不必相同,但是其大小和位置必须是可知的。
这个类在很多资料上翻译成中文都是:随机访问文件,在中文里,随机是具有不确定的含义,指一会访问这里,一会访问那里的意思。如果以这种语义来解释的话,就会感到很困惑。其实,Random在英文中不仅仅有随机,还有任意的意思。如果中文名为任意访问文件是不是就会更好的理解。任意表示我们可以指定文件中任何一个位置去操作一个文件。
4.实际项目举例:
比如接到一个任务向一个已经有2G数据得txt文本里面末尾追加一行字,比如“我爱我家”。我们可能会直接将2G文件中得内容读取出来,然后转换成字符串,再用连接符将要新添加得这一行加上。可以,如果当这个数据文件变得越来越大,比如达到8G,可以我们得开发剩余内存只有5G。倘若我们还是采取老办法,强制读取数据并追加,则会产生内存溢出得异常现象。因此,就有了RandomAccessFile得产生。它可以进行任意访问,程序可以直接跳到任意地方来读写数据。我们不再需要将文件从头读到尾,只需要指定位置访问数据就行。
三. RandomAccessFile模式说明
RandomAccessFile共有4种模式:"r", "rw", "rws"和"rwd"。
<strong>"r"</strong> 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。 <strong>"rw"</strong> 打开以便读取和写入。 <strong>"rws" </strong> 打开以便读取和写入。相对于 "rw","rws" 还要求对“文件的内容”或“元数据”的每个更新都同步写入到基础存储设备。 <strong>"rwd" </strong> 打开以便读取和写入,相对于 "rw","rwd" 还要求对“文件的内容”的每个更新都同步写入到基础存储设备。
说明:
1. 什么是“元数据”,即metadata?
英文解释如下:
The definition of metadata is "data about other data." With a file system, the data is contained in its files and directories, and the metadata tracks information about each of these objects: Is it a regular file, a directory, or a link? What is its size, creation date, last modified date, file owner, group owner, and access permissions?
大致意思是:
metadata是“关于数据的数据”。在文件系统中,数据被包含在文件和文件夹中;metadata信息包括:“数据是一个文件,一个目录还是一个链接”,“数据的创建时间(简称ctime)”,“最后一次修改时间(简称mtime)”,“数据拥有者”,“数据拥有群组”,“访问权限”等等。
2. "rw", "rws", "rwd" 的区别。
当操作的文件是存储在本地的基础存储设备上时(如硬盘, NandFlash等),"rws" 或 "rwd", "rw" 才有区别。
当模式是 "rws" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]” 或 “修改文件元数据(如文件的mtime)”时,都会将这些改变同步到基础存储设备上。
当模式是 "rwd" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]”时,都会将这些改变同步到基础存储设备上。
当模式是 "rw" 并且 操作的是基础存储设备上的文件;那么,关闭文件时,会将“文件内容的修改”同步到基础存储设备上。至于,“更改文件内容”时,是否会立即同步,取决于系统底层实现。
四. RandomAccessFile使用方法
下面来看下RandomAccessFile类中比较重要的2个方法,其他的和普通IO类似,在这里,就不详细说明了。
| 方法名 | 作用 |
| getFilePointer() | 返回文件记录指针的当前位置 |
| seek(long pos) | 将文件记录指针定位到pos的位置 |
<span style="color: #008080"> 1</span> <span style="color: #0000ff">package</span><span style="color: #000000"> com.test.a;
</span><span style="color: #008080"> 2</span>
<span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> java.io.IOException;
</span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> java.io.RandomAccessFile;
</span><span style="color: #008080"> 5</span>
<span style="color: #008080"> 6</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Test {
</span><span style="color: #008080"> 7</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{
</span><span style="color: #008080"> 8</span> RandomAccessFile accessFile=<span style="color: #0000ff">new</span> RandomAccessFile("C:UsershermionerDesktoptest.txt", "r"<span style="color: #000000">);
</span><span style="color: #008080"> 9</span> System.out.println("RandomAccessFeile文件指针的初始位置:"+accessFile.getFilePointer());<span style="color: #008000">//</span><span style="color: #008000">1.</span>
<span style="color: #008080">10</span> accessFile.seek(10<span style="color: #000000">);
</span><span style="color: #008080">11</span> System.out.println("RandomAccessFeile文件指针的初始位置:"+<span style="color: #000000">accessFile.getFilePointer());
</span><span style="color: #008080">12</span> <span style="color: #0000ff">byte</span> buffer[]=<span style="color: #0000ff">new</span> <span style="color: #0000ff">byte</span>[40<span style="color: #000000">];
</span><span style="color: #008080">13</span> <span style="color: #0000ff">int</span> hasRead=0<span style="color: #000000">;
</span><span style="color: #008080">14</span> <span style="color: #0000ff">while</span>((hasRead=accessFile.read(buffer))>0<span style="color: #000000">) {
</span><span style="color: #008080">15</span> <span style="color: #000000"> System.out.println(hasRead);
</span><span style="color: #008080">16</span> System.out.println("RandomAccessFeile文件指针的初始位置:"+<span style="color: #000000">accessFile.getFilePointer());
</span><span style="color: #008080">17</span> System.out.println(<span style="color: #0000ff">new</span> String(buffer,0<span style="color: #000000">,hasRead));
</span><span style="color: #008080">18</span> <span style="color: #000000"> }
</span><span style="color: #008080">19</span>
<span style="color: #008080">20</span> <span style="color: #000000"> }
</span><span style="color: #008080">21</span> <span style="color: #000000">}
</span><span style="color: #008080">22</span> <span style="color: #008000">/**</span>
<span style="color: #008080">23</span> <span style="color: #008000"> * 1.第一处返回文件记录指针为0,即文本得最开始处。
</span><span style="color: #008080">24</span> <span style="color: #008000"> * 2.当执行了seek(10)以后,就跳了10个字符,这是得文件记录指针应该在10
</span><span style="color: #008080">25</span> <span style="color: #008000"> * 3.开始任意位置读取数据,一次读取hasRead个,最多读取40个。
</span><span style="color: #008080">26</span> <span style="color: #008000"> * 4.第一次读取了40个,即此时得指针应该移动到了40+10=50处
</span><span style="color: #008080">27</span> <span style="color: #008000"> * 5.第二次开始读取,只读取了34个(其中包含了一个换行符,因此实际上跳动了34个位置,即已经读取完了,此时应该在84位置处)。
</span><span style="color: #008080">28</span> <span style="color: #008000">*/</span>
<span style="color: #008080">29</span>
<span style="color: #008080">30</span> <span style="color: #008000">//</span><span style="color: #008000">RandomAccessFeile文件指针的初始位置:0
</span><span style="color: #008080">31</span> <span style="color: #008000">//</span><span style="color: #008000">RandomAccessFeile文件指针的初始位置:10
</span><span style="color: #008080">32</span> <span style="color: #008000">//</span><span style="color: #008000">40
</span><span style="color: #008080">33</span> <span style="color: #008000">//</span><span style="color: #008000">RandomAccessFeile文件指针的初始位置:50
</span><span style="color: #008080">34</span> <span style="color: #008000">//</span><span style="color: #008000">life,I love my family.
</span><span style="color: #008080">35</span> <span style="color: #008000">//</span><span style="color: #008000">I want to become
</span><span style="color: #008080">36</span> <span style="color: #008000">//</span><span style="color: #008000">34
</span><span style="color: #008080">37</span> <span style="color: #008000">//</span><span style="color: #008000">RandomAccessFeile文件指针的初始位置:84
</span><span style="color: #008080">38</span> <span style="color: #008000">//</span><span style="color: #008000"> a professional software engineer.</span>
View Code
note: test.txt文档中的内容如下:

2. seek
<span style="color: #008080"> 1</span> <span style="color: #0000ff">package</span><span style="color: #000000"> com.test.a;
</span><span style="color: #008080"> 2</span>
<span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> java.io.IOException;
</span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> java.io.RandomAccessFile;
</span><span style="color: #008080"> 5</span>
<span style="color: #008080"> 6</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Test {
</span><span style="color: #008080"> 7</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{
</span><span style="color: #008080"> 8</span> <span style="color: #008000">//</span><span style="color: #008000">以读写的方式创建了一个对象</span>
<span style="color: #008080"> 9</span> RandomAccessFile accessFile=<span style="color: #0000ff">new</span> RandomAccessFile("C:UsershermionerDesktoptest.txt", "rw"<span style="color: #000000">);
</span><span style="color: #008080">10</span> accessFile.seek(2<span style="color: #000000">);
</span><span style="color: #008080">11</span> <span style="color: #000000"> System.out.println(accessFile.getFilePointer());
</span><span style="color: #008080">12</span> accessFile.seek(2<span style="color: #000000">);
</span><span style="color: #008080">13</span> <span style="color: #000000"> System.out.println(accessFile.getFilePointer());
</span><span style="color: #008080">14</span> <span style="color: #000000"> }
</span><span style="color: #008080">15</span> }
View Code
说明:seek(number)可以用来每次定位到什么地方。当读取文件的时候,如果不去调用这个方法,getFilePointer的时候,会随着读取的位置变动而变动;倘若调用了seek,每次即使读取了数据位置有变动,一旦调用seek,就会回到seek指定的这个number处来,即getFilePointer等于这个Number.
3. 追加数据
<span style="color: #008080"> 1</span> <span style="color: #0000ff">package</span><span style="color: #000000"> com.test.a;
</span><span style="color: #008080"> 2</span>
<span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> java.io.IOException;
</span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> java.io.RandomAccessFile;
</span><span style="color: #008080"> 5</span>
<span style="color: #008080"> 6</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Test {
</span><span style="color: #008080"> 7</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{
</span><span style="color: #008080"> 8</span> <span style="color: #008000">//</span><span style="color: #008000">以读写的方式创建了一个对象</span>
<span style="color: #008080"> 9</span> RandomAccessFile accessFile=<span style="color: #0000ff">new</span> RandomAccessFile("C:UsershermionerDesktoptest.txt", "rw"<span style="color: #000000">);
</span><span style="color: #008080">10</span> <span style="color: #008000">//</span><span style="color: #008000">将记录指针移动到文件的最后进行追加</span>
<span style="color: #008080">11</span> <span style="color: #000000"> accessFile.seek(accessFile.length());
</span><span style="color: #008080">12</span> accessFile.write("I can success"<span style="color: #000000">.getBytes());
</span><span style="color: #008080">13</span> <span style="color: #000000"> }
</span><span style="color: #008080">14</span> <span style="color: #000000">}
</span><span style="color: #008080">15</span>
<span style="color: #008080">16</span>
<span style="color: #008080">17</span> <span style="color: #000000">I love my life,I love my family.
</span><span style="color: #008080">18</span> I want to become a professional software engineer.I can success
View Code
4. 任意位置插入数据
<span style="color: #008080"> 1</span> <span style="color: #008000">/**</span>
<span style="color: #008080"> 2</span> <span style="color: #008000"> * 实现向指定位置
</span><span style="color: #008080"> 3</span> <span style="color: #008000"> * 插入数据
</span><span style="color: #008080"> 4</span> <span style="color: #008000"> * </span><span style="color: #808080">@param</span><span style="color: #008000"> fileName 文件名
</span><span style="color: #008080"> 5</span> <span style="color: #008000"> * </span><span style="color: #808080">@param</span><span style="color: #008000"> points 指针位置
</span><span style="color: #008080"> 6</span> <span style="color: #008000"> * </span><span style="color: #808080">@param</span><span style="color: #008000"> insertContent 插入内容
</span><span style="color: #008080"> 7</span> <span style="color: #008000"> * *</span><span style="color: #008000">*/</span>
<span style="color: #008080"> 8</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: #008080"> 9</span> <span style="color: #0000ff">try</span><span style="color: #000000">{
</span><span style="color: #008080">10</span> File tmp=File.createTempFile("tmp", <span style="color: #0000ff">null</span><span style="color: #000000">);
</span><span style="color: #008080">11</span> tmp.deleteOnExit();<span style="color: #008000">//</span><span style="color: #008000">在JVM退出时删除 </span>
<span style="color: #008080">12</span>
<span style="color: #008080">13</span> RandomAccessFile raf=<span style="color: #0000ff">new</span> RandomAccessFile(fileName, "rw"<span style="color: #000000">);
</span><span style="color: #008080">14</span> <span style="color: #008000">//</span><span style="color: #008000">创建一个临时文件夹来保存插入点后的数据 </span>
<span style="color: #008080">15</span> FileOutputStream tmpOut=<span style="color: #0000ff">new</span><span style="color: #000000"> FileOutputStream(tmp);
</span><span style="color: #008080">16</span> FileInputStream tmpIn=<span style="color: #0000ff">new</span><span style="color: #000000"> FileInputStream(tmp);
</span><span style="color: #008080">17</span> <span style="color: #000000"> raf.seek(points);
</span><span style="color: #008080">18</span> <span style="color: #008000">/**</span><span style="color: #008000">将插入点后的内容读入临时文件夹*</span><span style="color: #008000">*/</span>
<span style="color: #008080">19</span>
<span style="color: #008080">20</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: #008080">21</span> <span style="color: #008000">//</span><span style="color: #008000">用于保存临时读取的字节数 </span>
<span style="color: #008080">22</span> <span style="color: #0000ff">int</span> hasRead=0<span style="color: #000000">;
</span><span style="color: #008080">23</span> <span style="color: #008000">//</span><span style="color: #008000">循环读取插入点后的内容 </span>
<span style="color: #008080">24</span> <span style="color: #0000ff">while</span>((hasRead=raf.read(buff))>0<span style="color: #000000">){
</span><span style="color: #008080">25</span> <span style="color: #008000">//</span><span style="color: #008000"> 将读取的数据写入临时文件中 </span>
<span style="color: #008080">26</span> tmpOut.write(buff, 0<span style="color: #000000">, hasRead);
</span><span style="color: #008080">27</span> <span style="color: #000000"> }
</span><span style="color: #008080">28</span>
<span style="color: #008080">29</span> <span style="color: #008000">//</span><span style="color: #008000">插入需要指定添加的数据 </span>
<span style="color: #008080">30</span> raf.seek(points);<span style="color: #008000">//</span><span style="color: #008000">返回原来的插入处
</span><span style="color: #008080">31</span> <span style="color: #008000">//</span><span style="color: #008000">追加需要追加的内容 </span>
<span style="color: #008080">32</span> <span style="color: #000000"> raf.write(insertContent.getBytes());
</span><span style="color: #008080">33</span> <span style="color: #008000">//</span><span style="color: #008000">最后追加临时文件中的内容 </span>
<span style="color: #008080">34</span> <span style="color: #0000ff">while</span>((hasRead=tmpIn.read(buff))>0<span style="color: #000000">){
</span><span style="color: #008080">35</span> raf.write(buff,0<span style="color: #000000">,hasRead);
</span><span style="color: #008080">36</span> <span style="color: #000000"> }
</span><span style="color: #008080">37</span> }<span style="color: #0000ff">catch</span><span style="color: #000000">(Exception e){
</span><span style="color: #008080">38</span> <span style="color: #000000"> e.printStackTrace();
</span><span style="color: #008080">39</span> <span style="color: #000000"> }
</span><span style="color: #008080">40</span> }
View Code
说明:这里插入内容的原理就是:先把插入点后面的内容读入缓冲区,等插入完成后,再讲缓冲区(通过tempout写到了buffer中)的内容追加到文件的后面。
note:RandomAccessFile本身是没有这个任意位置插入数据的方法的。
文献参考:
https://www.cnblogs.com/zuochengsi-9/p/6485737.html
https://www.cnblogs.com/skywang12345/p/io_26.html
https://www.cnblogs.com/dongguacai/p/5699444.html
23 Java学习之RandomAccessFile
标签:内容 元数据 ram 文件系统 说明 use ini link inf
本文系统来源:https://www.cnblogs.com/Hermioner/p/9775023.html
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!