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. 菜鸟学SSH(十九)——提高用户体验之404处理

    只要做过WEB开发人对于“404”已经再熟悉不过了吧.当我们访问的资源不存在时,它就会跑出来跟你打招呼啦.但是默认情况下,404页面比较简陋,不是很友好.而且一般用户不知道404是个神马东东,还以为是 ...

  2. [转]protoc-gen-lua 编译、安装、使用教程

    版权声明:本文转自http://blog.csdn.net/huutu 转载请带上 http://www.liveslives.com/ https://blog.csdn.net/cp7906216 ...

  3. 【css】css 中文字体 unicode 对照表

    css 中文字体可以用 unicode 格式来表示,比如“宋体”可以用 \5B8B\4F53 来表示.具体参考下表: 中文名 英文名 unicode 宋体 SimSun \5B8B\4F53 黑体 S ...

  4. Java知多少(29)覆盖和重载

    在类继承中,子类可以修改从父类继承来的方法,也就是说子类能创建一个与父类方法有不同功能的方法,但具有相同的名称.返回值类型.参数列表. 如果在新类中定义一个方法,其名称.返回值类型和参数列表正好与父类 ...

  5. Oracle Grid 11.2.0.4 安装是出现"INS-30510: Insufficient number of ASM disks selected."

    最新文章:Virson's Blog 错误的原因是由于磁盘数和冗余层级不匹配: 如果创建用来存放OCR和VOTEDISK的ASM磁盘组,那么External.Normal.High三种冗余级别对应的F ...

  6. 避免在构造函数中调用虚方法(Do not call overridable methods in constructors)

    CLR中说道,不要在构造函数中调用虚方法,原因是假如被实例化的类型重写了虚方法,就会执行派生类型对虚方法的实现.但在这个时候,尚未完成对继承层次结构中所有字段的初始化.所以,调用虚方法会导致不可预测的 ...

  7. [Tensorflow] Object Detection API - retrain mobileNet

    前言 一.专注话题 重点话题 Retrain mobileNet (transfer learning). Train your own Object Detector. 这部分讲理论,下一篇讲实践. ...

  8. [Artoolkit] Marker Training

    Link: Documentation About the Traditional Template Square Marker Limitations (重要) Traditional Templa ...

  9. Mac 环境 Vue 开发 CPU 占用率高 问题

    Mac开发Vue应用时,发现CPU风扇转的老高. htop查看一下: 问题找到了,就是这个dev-server.js,node起的进程. 然后就是 dtruss -p 1230(进程ID) 命名跟踪一 ...

  10. Spring Boot 集成 Redis 实现缓存机制

    本文章牵涉到的技术点比较多:spring Data JPA.Redis.Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章 ...