RandomAccessFile是Java输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据。与普通的输入/输出流不同的是,RandomAccessFile支持“随机访问”的方式,程序可以直接跳转到文件的任意地方来读写数据。

  由于RandomAccessFile可以自由访问文件的任意位置,所以如果只需要访问文件部分内容,而不是把文件从头读到尾,使用RandomAccessFile将是更好的选择。

  RandomAccessFile方法虽然多,但它有一个最大的局限,就是只能读写文件,不能读写其它IO节点。

  RandomAccessFile对象也包含了一个记录指针,用以标识当前读写的位置,当程序新创建一个RandomAccessFile对象时,该对象的文件记录指针位于文件头(也就是0处),当读/写了n个字节后,文件记录指针将会向后移动n个字节。除此之外,RandomAccessFile可以自由移动该记录指针。RandomAccessFile包含了两个方法来操作文件记录指针。

Constructors 
Constructor Description
RandomAccessFile​(File file, String mode)
Creates a random access file stream to read from, and optionally to write to, the file specified by the File argument.      4种mode:                                                                                                                   
(1)"r":只读模式打开指定文件。如果试图对该RandomAccessFile执行写入方法,都将抛出IOException异常;
(2)"rw":以读、写方式打开指定文件。如果文件尚不存在,则尝试创建该文件;
(3)"rws":以读、写方式打开指定文件。相对于"rw"模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备;
(4)"rwd":以读、写方式打开指定文件。相对于"rw"模式,还要求对文件内容的每个更新都同步写入到底层存储设备。
RandomAccessFile​(String name, String mode)
Creates a random access file stream to read from, and optionally to write to, a file with the specified name.
All Methods Instance Methods Concrete Methods 
Modifier and Type Method Description
void close​()
Closes this random access file stream and releases any system resources associated with the stream.
FileChannel getChannel​()
Returns the unique FileChannel object associated with this file.
FileDescriptor getFD​()
Returns the opaque file descriptor object associated with this stream.
long getFilePointer​()
Returns the current offset in this file.(返回文件记录指针的当前位置)
long length​()
Returns the length of this file.
int read​()
Reads a byte of data from this file.
int read​(byte[] b)
Reads up to b.length bytes of data from this file into an array of bytes.
int read​(byte[] b,    int off,    int len)
Reads up to len bytes of data from this file into an array of bytes.
boolean readBoolean​()
Reads a boolean from this file.
byte readByte​()
Reads a signed eight-bit value from this file.
char readChar​()
Reads a character from this file.
double readDouble​()
Reads a double from this file.
float readFloat​()
Reads a float from this file.
void readFully​(byte[] b)
Reads b.length bytes from this file into the byte array, starting at the current file pointer.
void readFully​(byte[] b,         int off,         int len)
Reads exactly len bytes from this file into the byte array, starting at the current file pointer.
int readInt​()
Reads a signed 32-bit integer from this file.
String readLine​()
Reads the next line of text from this file.
long readLong​()
Reads a signed 64-bit integer from this file.
short readShort​()
Reads a signed 16-bit number from this file.
int readUnsignedByte​()
Reads an unsigned eight-bit number from this file.
int readUnsignedShort​()
Reads an unsigned 16-bit number from this file.
String readUTF​()
Reads in a string from this file.
void seek​(long pos)
Sets the file-pointer offset, measured from the beginning of this file, at which the next read or write occurs.(将文件记录指针定位到pos位置)
void setLength​(long newLength)
Sets the length of this file.
int skipBytes​(int n)
Attempts to skip over n bytes of input discarding the skipped bytes.
void write​(byte[] b)
Writes b.length bytes from the specified byte array to this file, starting at the current file pointer.
void write​(byte[] b,     int off,     int len)
Writes len bytes from the specified byte array starting at offset off to this file.
void write​(int b)
Writes the specified byte to this file.
void writeBoolean​(boolean v)
Writes a boolean to the file as a one-byte value.
void writeByte​(int v)
Writes a byte to the file as a one-byte value.
void writeBytes​(String s)
Writes the string to the file as a sequence of bytes.
void writeChar​(int v)
Writes a char to the file as a two-byte value, high byte first.
void writeChars​(String s)
Writes a string to the file as a sequence of characters.
void writeDouble​(double v)
Converts the double argument to a long using the  doubleToLongBits method in class Double, and then writes that long value to the file as an eight-byte quantity, high byte first.
void writeFloat​(float v)
Converts the float argument to an int using the  floatToIntBits method in class Float, and then writes that int value to the file as a four-byte quantity, high byte first.
void writeInt​(int v)
Writes an int to the file as four bytes, high byte first.
void writeLong​(long v)
Writes a long to the file as eight bytes, high byte first.
void writeShort​(int v)
Writes a short to the file as two bytes, high byte first.
void writeUTF​(String str)
Writes a string to the file using  modified UTF-8 encoding in a machine-independent manner.
 package com.zyjhandsome.io;

 import java.io.*;

 public class RandomAccessFileTest {

     public static void main(String[] args) {
// TODO Auto-generated method stub
try {
RandomAccessFile raf = new RandomAccessFile("D:\\zhaoyingjun\\eclipse-workspace\\CollectionTest\\src\\com\\zyjhandsome\\io\\RandomAccessFileTest.java", "r");
// 获取RandomAccessFile对象文件指针的位置,初始位置是0
System.out.println("RandomAccessFile的文件指针的初始位置:" + raf.getFilePointer());
// 移动raf文件的文件记录指针的位置
raf.seek(300);
byte[] bbuf = new byte[1024];
// 用于保存实际读取的字节数
int hasRead = 0;
// 使用循环来重复“取水”过程
// while ( (hasRead = raf.read(bbuf)) > 0 )
// {
// // 取出“竹简”中水滴(字节),将字节数组转换成字符串输入
// System.out.print(new String(bbuf, 0, hasRead));
// }
// 第二种写法
while ( (hasRead = raf.read()) > 0 )
{
// 取出“竹简”中水滴(字节),将字节数组转换成字符串输入
System.out.print((char)hasRead);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
 RandomAccessFile的文件指针的初始位置:0
me\\io\\RandomAccessFileTest.java", "r");
// ????RandomAccessFile???ó??????????????????????????0
System.out.println("RandomAccessFile??????????????????????" + raf.getFilePointer());
// ????raf????????????????????????
raf.seek(300);
byte[] bbuf = new byte[1024];
// ????±?????????????×?????
int hasRead = 0;
// ???????·???????°?????±????
// while ( (hasRead = raf.read(bbuf)) > 0 )
// {
// // ?????°???ò?±???????¨×?????????×?????×é×?????×?·???????
// System.out.print(new String(bbuf, 0, hasRead));
// }
// ????????·¨
while ( (hasRead = raf.read()) > 0 )
{
// ?????°???ò?±???????¨×?????????×?????×é×?????×?·???????
System.out.print((char)hasRead);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

  下面程序示范了如何向指定文件后追加内容,为了追加内容,程序应该先将记录指针移动到文件最后,然后开始向文件中输出内容。

 package com.zyjhandsome.io;

 import java.io.*;

 public class AppendContent {

     public static void main(String[] args) {
// TODO Auto-generated method stub
try {
RandomAccessFile raf = new RandomAccessFile("D:\\zhaoyingjun\\else\\Test\\AppendContent.txt", "rw");
// 将记录指针移动到AppendContent.txt文件的最后
raf.seek(raf.length());
// raf.writeChars("追加的内容!\r\n"); // 会出现乱码
// raf.writeChars("Hello, world\r\n"); //
raf.write("追加的内容!\r\n".getBytes());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

  RandomAccessFile依然不能向文件的指定位置插入内容,如果直接将文件记录指针移动到中间某位置后开始输出,则新输出的内容会覆盖文件中原有的内容。如果需要向指定位置插入内容,程序需要先把插入点后面的内容读入缓冲区,等把需要插入的数据写入文件后,再将缓冲区的内容追加到文件后面。

 package com.zyjhandsome.io;

 import java.io.*;

 public class InsertContent {

     public static void insert(String fileName, long pos, String insertContent) throws IOException
{
File tmp = File.createTempFile("tmp", null);
tmp.deleteOnExit();
try {
RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
// 使用临时文件来保存插入点后的数据
FileOutputStream tmpOut = new FileOutputStream(tmp);
FileInputStream tmpIn = new FileInputStream(tmp);
raf.seek(pos);
// --------下面代码将插入点后的内容读入临时文件中保存--------
byte[] bbuf = new byte[64];
// 用于保存实际读取的字节数
int hasRead = 0;
// 使用循环方式读取插入点后的数据
while ( (hasRead = raf.read()) > 0 )
{
tmpOut.write(hasRead);
}
// --------下面代码用于插入内容--------
// 把文件记录指针重新定位到pos位置
raf.seek(pos);
// 追加需要插入的内容
raf.write(insertContent.getBytes());
// --------追加临时文件中的内容--------
while ( (hasRead = tmpIn.read()) > 0)
{
raf.write((char)hasRead);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
insert("D:\\zhaoyingjun\\eclipse-workspace\\CollectionTest\\src\\com\\zyjhandsome\\io\\InsertContent.java", 45, "//插入的内容\r\n ");
}
}

  输出结果(查看InsertContent.java文件):

 package com.zyjhandsome.io;

 import java.io//插入的内容
.*; public class InsertContent { public static void insert(String fileName, long pos, String insertContent) throws IOException
{
File tmp = File.createTempFile("tmp", null);
tmp.deleteOnExit();
try {
RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
// 使用临时文件来保存插入点后的数据
FileOutputStream tmpOut = new FileOutputStream(tmp);
FileInputStream tmpIn = new FileInputStream(tmp);
raf.seek(pos);
// --------下面代码将插入点后的内容读入临时文件中保存--------
byte[] bbuf = new byte[64];
// 用于保存实际读取的字节数
int hasRead = 0;
// 使用循环方式读取插入点后的数据
while ( (hasRead = raf.read()) > 0 )
{
tmpOut.write(hasRead);
}
// --------下面代码用于插入内容--------
// 把文件记录指针重新定位到pos位置
raf.seek(pos);
// 追加需要插入的内容
raf.write(insertContent.getBytes());
// --------追加临时文件中的内容--------
while ( (hasRead = tmpIn.read()) > 0)
{
raf.write((char)hasRead);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
insert("D:\\zhaoyingjun\\eclipse-workspace\\CollectionTest\\src\\com\\zyjhandsome\\io\\InsertContent.java", 45, "//插入的内容\r\n ");
}
}

Java 输入/输出——处理流(RandomAccessFile)的更多相关文章

  1. Java 输入/输出——处理流(BufferedStream、PrintStream、转换流、推回输入流)

    关于使用处理流的优势,归纳起来就是两点:(1)对于开发人员来说,使用处理流进行输入/输出操作更简单:(2)使用处理流执行效率更高. 1.BufferedInputStream/BufferedOutp ...

  2. Java 输入/输出——处理流(ObjectIO)

    Object流:直接将Object流写入或读出. TestObjectIO.java transient关键字(英文名:透明的,可以用来修饰成员变量(实例变量),transient修饰的成员变量(实例 ...

  3. Java 输入/输出——处理流(DataInputStream/DataOutputStream、ByteArrayInputStream/ByteArrayOutputStream)

    DataInputStream和DataOutputStream分别继承字节流InputStream和OutputStream,它属于处理流,需要分别“套接”在InputStream和OutputSt ...

  4. Java 输入/输出 反射

    Java  输入/输出   反射 输入输出和反射 一.数据流的基本概念 流一般分为 ( Input Stream ) 和输出流 ( Output Stream ) 两类,但这种划分并不是绝对的.比如一 ...

  5. Java输入/输出教程

    Java输入/输出(I/O)处理从源读取数据并将数据写入目标.通常,读取存储在文件中的数据或使用I/O将数据写入到文件中. java.io和java.nio包中包含处理输入/输出的Java类.java ...

  6. [linux] 输入&输出&错误流

    输入&输出&错误流 Linux中有三种标准输入输出,分别是STDIN,STDOUT,STDERR,对应的数字分别是0,1,2. 标准 数字 含义 STDIN 0 标准输入,默认从键盘读 ...

  7. JAVA输入/输出系统中的其他流学习笔记

    一.字节数组流 字节数组流类能够操作内存中的字节数组,它的数据是一个字节数组.字节数组流类本身适配器设计模式,它把字节数组类型转为流类型使得程序能够对字节数组进行读写操作. 1.ByteArrayIn ...

  8. Java 输入/输出——字节流和字符流

    1.流的分类 (1)输入流和输出流(划分输入/输出流时是从程序运行所在内存的角度来考虑的) 输入流:只能从中读取数据,而不能向其写入数据. 输出流:只能向其写入数据,而不能从中读取数据. 输入流主要由 ...

  9. Java输入/输出(I/O)流的分类总结

    java.io中有四个重要的抽象类: InputStream(字节输入流) Reader(字符输入流) OutputStream(字节输出流) Writer(字符输出流) 其中,InputStream ...

随机推荐

  1. 浏览器对HTML5特性检測工具Modernizr

    近期在做公司移动端运营的项目,需求中多处地方都会涉及动画. 相信非常多前端开发都会有这样的感触,对CSS3中的动画属性非常熟悉,可是因为对动画运动过程的理解不深入,经常仅仅能望而止步.CSS3中动画这 ...

  2. mysql索引hash索引和b-tree索引的区别

    Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...

  3. .NET+MVC+ORACLE存储分页查询一前端实现

    MemberList.cshtml @{    ViewBag.Title = "用户列表";    Layout = null;} <!DOCTYPE html> & ...

  4. Linux之sort

    sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分钟搞定sort,现在开始! 1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按AS ...

  5. LeetCode: Best Time to Buy and Sell Stock III 解题报告

    Best Time to Buy and Sell Stock IIIQuestion SolutionSay you have an array for which the ith element ...

  6. 【Java】Comparable和Comparator接口的区别

    Java提供了只包含一个compareTo()方法的Comparable接口.这个方法可以个给两个对象排序.具体来说,它返回负数,0,正数来表明已经存在的对象小于,等于,大于输入对象. Java提供了 ...

  7. 编译错误“The run destination My Mac is not valid for Running the scheme '***',解决办法

    [转载]   http://blog.csdn.net/duanyipeng/article/details/8007684   编译错误"The run destination My Ma ...

  8. [ModemManger]ModemManger的取消

    http://www.linux-databook.info/?page_id=3748 systemctl disable ModemManager.service 失能ModemManger从而取 ...

  9. Java 同时返回多个不同类型的方法

    Java 同时返回多个不同类型的方法 2016年12月02日 16:05:07 FXBStudy 阅读数:10045   前言:虽然对于这种需求不常用,且比较冷门,但是还是有其存在的价值,再次做一下整 ...

  10. mysql解除死锁状态

    方案一: 1.查看是否有锁表 show OPEN TABLES ; 2.查询进程(如果你有SUPER权限,你可以看到所有线程.否则,只能看到你自己的线程) show processlist; 3.杀死 ...