java io系列26之 RandomAccessFile

简介: 本文主要介绍 RandomAccessFile。 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_26.html 更多内容请参考:java io系列01之 "目录"   RandomAccessFile RandomAccessFile 是随机访问文件(包括读/写)的类。

本文主要介绍 RandomAccessFile。

转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_26.html

更多内容请参考:java io系列01之 "目录"

 

RandomAccessFile

RandomAccessFile 是随机访问文件(包括读/写)的类。它支持对文件随机访问的读取和写入,即我们可以从指定的位置读取/写入文件数据。
需 要注意的是,RandomAccessFile 虽然属于java.io包,但它不是InputStream或者OutputStream的子类;它也不同于FileInputStream和 FileOutputStream。 FileInputStream 只能对文件进行读操作,而FileOutputStream 只能对文件进行写操作;但是,RandomAccessFile 同时支持文件的读和写,并且它支持随机访问。

 

RandomAccessFile 函数列表

复制代码
RandomAccessFile(File file, String mode)
RandomAccessFile(String fileName, String mode)

void     close()
synchronized final FileChannel getChannel() final FileDescriptor getFD() long getFilePointer() long length() int read(byte[] buffer, int byteOffset, int byteCount) int read(byte[] buffer) int read() final boolean readBoolean() final byte readByte() final char readChar() final double readDouble() final float readFloat() final void readFully(byte[] dst) final void readFully(byte[] dst, int offset, int byteCount) final int readInt() final String readLine() final long readLong() final short readShort() final String readUTF() final int readUnsignedByte() final int readUnsignedShort() void seek(long offset) void setLength(long newLength) int skipBytes(int count) void write(int oneByte) void write(byte[] buffer, int byteOffset, int byteCount) void write(byte[] buffer) final void writeBoolean(boolean val) final void writeByte(int val) final void writeBytes(String str) final void writeChar(int val) final void writeChars(String str) final void writeDouble(double val) final void writeFloat(float val) final void writeInt(int val) final void writeLong(long val) final void writeShort(int val) final void writeUTF(String str)
复制代码

 

1. RandomAccessFile 模式说明

RandomAccessFile共有4种模式:"r", "rw", "rws"和"rwd"。

"r"    以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。  
"rw"   打开以便读取和写入。
"rws"  打开以便读取和写入。相对于 "rw","rws" 还要求对“文件的内容”或“元数据”的每个更新都同步写入到基础存储设备。  
"rwd"  打开以便读取和写入,相对于 "rw","rwd" 还要求对“文件的内容”的每个更新都同步写入到基础存储设备。  

说明
(01) 什么是“元数据”,即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)”,“数据拥有者”,“数据拥有群组”,“访问权限”等等。

(02) "rw", "rws", "rwd" 的区别。
当操作的文件是存储在本地的基础存储设备上时(如硬盘, NandFlash等),"rws" 或 "rwd", "rw" 才有区别。
当模式是 "rws" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]” 或 “修改文件元数据(如文件的mtime)”时,都会将这些改变同步到基础存储设备上。
当模式是 "rwd" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]”时,都会将这些改变同步到基础存储设备上。
当模式是 "rw" 并且 操作的是基础存储设备上的文件;那么,关闭文件时,会将“文件内容的修改”同步到基础存储设备上。至于,“更改文件内容”时,是否会立即同步,取决于系统底层实现。

 

2. 演示程序

源码如下

复制代码
  1 import java.io.File;
  2 import java.io.FileDescriptor;  3 import java.io.FileInputStream;  4 import java.io.FileOutputStream;  5 import java.io.BufferedInputStream;  6 import java.io.BufferedOutputStream;  7 import java.io.PrintStream;;  8 import java.io.RandomAccessFile;  9 import java.io.IOException;  10  11 /**  12  * RandomAccessFile 测试程序  13  *  14  * 运行结果(输出如下):  15  * c1=a  16  * c2=b  17  * buf=9876543210  18  *  19  * 此外,  20  * (01) 在源文件所在目录生成了file.txt。  21  * (02) 注意RandomAccessFile写入boolean, byte, char, int,所占的字符个数。  22  *  23  * @author skywang  24 */  25 public class RandomAccessFileTest {  26  27 private static final String FileName = "file.txt";  28  29 public static void main(String[] args) {  30 // 若文件“file.txt”存在,则删除该文件。  31 File file = new File(FileName);  32 if (file.exists())  33  file.delete();  34  35  testCreateWrite();  36  testAppendWrite();  37  testRead();  38  }  39  40 /**  41  * 若“file.txt”不存在的话,则新建文件,并向文件中写入内容  42 */  43 private static void testCreateWrite() {  44 try {  45 // 创建文件“file.txt”对应File对象  46 File file = new File(FileName);  47 // 创建文件“file.txt”对应的RandomAccessFile对象  48 RandomAccessFile raf = new RandomAccessFile(file, "rw");  49  50 // 向“文件中”写入26个字母+回车  51 raf.writeChars("abcdefghijklmnopqrstuvwxyz\n");  52 // 向“文件中”写入"9876543210"+回车  53 raf.writeChars("9876543210\n");  54  55  raf.close();  56 } catch(IOException e) {  57  e.printStackTrace();  58  }  59  }  60  61 /**  62  * 向文件末尾追加内容  63 */  64 private static void testAppendWrite() {  65 try {  66 // 创建文件“file.txt”对应File对象  67 File file = new File(FileName);  68 // 创建文件“file.txt”对应的RandomAccessFile对象  69 RandomAccessFile raf = new RandomAccessFile(file, "rw");  70  71 // 获取文件长度  72 long fileLen = raf.length();  73 // 将位置定位到“文件末尾”  74  raf.seek(fileLen);  75  76 // 以下向raf文件中写数据  77 raf.writeBoolean(true); // 占1个字节  78 raf.writeByte(0x41); // 占1个字节  79 raf.writeChar('a'); // 占2个字节 80 raf.writeShort(0x3c3c); // 占2个字节 81 raf.writeInt(0x75); // 占4个字节 82 raf.writeLong(0x1234567890123456L); // 占8个字节 83 raf.writeFloat(4.7f); // 占4个字节 84 raf.writeDouble(8.256);// 占8个字节 85 raf.writeUTF("UTF严"); // UTF-8格式写入 86 raf.writeChar('\n'); // 占2个字符。“换行符” 87 88 raf.close(); 89 } catch(IOException e) { 90 e.printStackTrace(); 91 } 92 } 93 94 /** 95 * 通过RandomAccessFile读取文件 96 */ 97 private static void testRead() { 98 try { 99 // 创建文件“file.txt”对应File对象 100 File file = new File(FileName); 101 // 创建文件“file.txt”对应的RandomAccessFile对象,以只读方式打开 102 RandomAccessFile raf = new RandomAccessFile(file, "r"); 103 104 // 读取一个字符 105 char c1 = raf.readChar(); 106 System.out.println("c1="+c1); 107 // 读取一个字符 108 char c2 = raf.readChar(); 109 System.out.println("c2="+c2); 110 111 // 跳过54个字节。 112 raf.seek(54); 113 114 // 测试read(byte[] buffer, int byteOffset, int byteCount) 115 byte[] buf = new byte[20]; 116 raf.read(buf, 0, buf.length); 117 System.out.println("buf="+(new String(buf))); 118 119 raf.close(); 120 } catch(IOException e) { 121 e.printStackTrace(); 122 } 123 } 124 }
复制代码

运行结果
c1=a
c2=b
buf=9876543210
结果说明
程序会在源文件所在目录生成file.txt;file.txt的内容如下:

file.txt对应的16进制内容如下:

 

相关文章
|
1月前
|
存储 Java 数据处理
|
1月前
|
Java API
java中IO与NIO有什么不同
java中IO与NIO有什么不同
|
3月前
|
存储 Java 数据安全/隐私保护
从零开始学习 Java:简单易懂的入门指南之IO字符流(三十一)
从零开始学习 Java:简单易懂的入门指南之IO字符流(三十一)
|
3月前
|
存储 移动开发 Java
从零开始学习 Java:简单易懂的入门指南之IO字节流(三十)
从零开始学习 Java:简单易懂的入门指南之IO字节流(三十)
|
3月前
|
存储 算法 Java
从零开始学习 Java:简单易懂的入门指南之IO序列化、打印流、压缩流(三十三)
从零开始学习 Java:简单易懂的入门指南之IO序列化、打印流、压缩流(三十三)
|
14天前
|
存储 Java
探索 Java IO 流的多种实现方式
【4月更文挑战第4天】Java IO 流是处理输入输出的关键组件,包括文件流(FileInputStream/FileOutputStream)、字符流(FileReader/FileWriter)、缓冲区流(BufferedInputStream/BufferedOutputStream)、转换流(InputStreamReader/OutputStreamWriter)、数据流(DataInputStream/DataOutputStream)、对象流(ObjectInputStream/ObjectOutputStream)、随机访问文件流(RandomAccessFile)和管道流。
|
26天前
|
Java 关系型数据库 MySQL
Flink1.18.1和CDC2.4.1 本地没问题 提交任务到服务器 报错java.lang.NoClassDefFoundError: Could not initialize class io.debezium.connector.mysql.MySqlConnectorConfig
【2月更文挑战第33天】Flink1.18.1和CDC2.4.1 本地没问题 提交任务到服务器 报错java.lang.NoClassDefFoundError: Could not initialize class io.debezium.connector.mysql.MySqlConnectorConfig
46 2
|
1月前
|
Java
|
2月前
|
Java 数据处理
如何玩转Java IO?
【2月更文挑战第7天】
218 0
如何玩转Java IO?
|
2月前
|
缓存 分布式计算 Java
Java基础深化和提高-------IO流
Java基础深化和提高-------IO流
108 0