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. IP子系统集成

    IP子系统集成 1.Creating External Connections 由此可以看出:block design的设计是可以连接电路板上的CPU的(外挂CPU). 2.生成外部接口 端口生成之后 ...

  2. 【Big Data - Hadoop - MapReduce】初学Hadoop之图解MapReduce与WordCount示例分析

    Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算. HDFS是Google File System(GFS) ...

  3. GNU Binutils简介及基本用法

    [时间:2017-06] [状态:Open] [关键词:GNU, binutils, as, ld, ar, 基础工具,linux,链接器,汇编器] 0 简介 GNU Binary Utilities ...

  4. (转载)完成端口(Completion Port, I/OCP)详解

    http://www.cnblogs.com/lancidie/archive/2011/12/19/2293773.html 手把手叫你玩转网络编程系列之三    完成端口(Completion P ...

  5. centos6.5安装mongodb2.6

    下载地址:http://www.mongodb.org/downloads 解压命令:tar zxf mongodb-linux-i686-2.6.0.tgz 存放目录:/usr/local/mong ...

  6. RDP 数据库简介

    在扩增子数据分析中,有时会发现多个OTU 注释到了同一个species ,  为什么会出现这种情况呢? 首先既然在OTU水平能分开,说明序列的相似度小于97%,  同一个物种的同一个基因的片段相似度会 ...

  7. centos7 网络配置

    vi /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPR ...

  8. 和我一起学Effective Java之类和接口

    类和接口 使类和成员的可访问性最小 信息隐藏(information hiding)/封装(encapsulation):隐藏模块内部数据和其他实现细节,通过API和其他模块通信,不知道其他模块的内部 ...

  9. Android异步处理系列文章四篇之四 AsyncTask的实现原理

    Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...

  10. [PGM] Temporal Models

    这里的一些东西只是将过去已有的东西用PGM解释了一遍,但优势还是明显的,对整体认识有帮助. Video: https://www.youtube.com/watch?v=ogs4Oj8KahQ& ...