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. 我的Android进阶之旅------>Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题

    Android 设备的CPU类型通常称为ABIs 问题描写叙述 解决方法 1解决之前的截图 2解决后的截图 3解决方法 4建议 为什么你须要重点关注so文件 App中可能出错的地方 其它地方也可能出错 ...

  2. 大津法---OTSU算法

    简介: 大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出.从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景 ...

  3. Thinkphp 关联模型和试图模型区别

    关联模型主要在多表操作时使用,比如 user表,user_role表,role表 user_role字段:uid,rid,它作为中间表,负责将user和role之间的,1对1,1对多,多对多的关系进行 ...

  4. java中的数据加密3 非对称加密

    非对称加密也加公钥加密,不对称算法使用一对密钥对,一个公钥,一个私钥,使用公钥加密的数据,只有私钥能解开(可用于加密):同时,使用私钥加密的数据,只有公钥能解开(签名).但是速度很慢(比私钥加密慢10 ...

  5. Git 标签操作

    允许有意义的名称到一个特定的版本库中的标签操作.Tom 决定标记他们的项目代码,以便他们以后可以更容易访问. 创建标签 让我们标记当前HEAD使用git tag命令.他提供的标记名称前加上-a选项,使 ...

  6. vs问题集

    ******将获取的所有的','换成'<br/>'********** data.Data.StandardSeating.replace(/,/g,"<br/>&q ...

  7. Java知多少(82)标签、按钮和按钮事件简介

    标签和按钮也许是图形界面中最常见的两种组件,按钮又总是与激发动作事件有关. 标签 标签(JLabel)是最简单的Swing组件.标签对象的作用是对位于其后的界面组件作说明.可以设置标签的属性,即前景色 ...

  8. 完全卸载MySQL

    1.先停止mysql服务,cmd模式下输入net stop mysql; 或者在图形服务面板停止mysql服务 2.进入控制面板卸载mysql; 3.windows+R运行“regedit”文件,打开 ...

  9. Angular 定时器$timeout和$interval,延时调用

    项目中有用到定时器定时刷新页面的数据,在网上查看了一些资料,整理了一下,备忘. $timeout 用法如下:$timeout(fn,[delay],[invokeApply]); fn:一个将被延迟执 ...

  10. js arrayBuffer 字节序问题,小端法,大端法

    原文博客 { var buffer = new ArrayBuffer(2) var bytes = new Uint16Array(buffer) bytes[0] = (65 << 8 ...