解决方案网站,wordpress标题序号,wordpress二级页面菜单,百度竞价排名商业模式Java语言有一个处理文件输入输出的RandomAccessFile类#xff0c;既可以读取文件内容#xff0c;也可以向文件输出数据。 RandomAccessFile类在国内的技术文档和书籍中都翻译为“随机访问文件”类#xff0c;确实令人不解。 在中文中“随机”的意思#xff1a;
不设任何条…Java语言有一个处理文件输入输出的RandomAccessFile类既可以读取文件内容也可以向文件输出数据。 RandomAccessFile类在国内的技术文档和书籍中都翻译为“随机访问文件”类确实令人不解。 在中文中“随机”的意思
不设任何条件随意的。顺应情势变化。
概率论中有一个术语“随机事件”很明显“随机”意味着不受人为控制的、不确定的。 把RandomAccessFile翻译为“随机访问文件”明显是词不达意的。因此为了更贴合原意本文中我们翻译为“随意存取文件”。 RandomAccessFile类的继承层次
RandomAccessFile不属于基本输入输出流I/O结构层次的一部分它直接继承自Object。除了其实现了DataInput以及DataOutput这两者亦由DataInputStream和DataOutputStream实现接口之外它们与InputStream或者OutputStream并无直接关系。
RandomAccessFile拥有与其他I/O流类完全不同的行为。 RandomAccessFile 既可以读取文件内容也可以向文件输出数据。同时RandomAccessFile 支持“随意访问”的方式程序可以直接跳转到文件的任意地方来读写数据。 RandomAccessFile类的有些功能类似于DataInputStream和DataOutputStream的组合使用可直接读取各种基本数据类型的数据。
随意存取文件的行为在低层存储文件类似于一个大型字节数组。刚打开文件时文件指针位于文件头部输入操作从文件指针开始读取字节并随着对字节的读取而前移此文件指针反之输出操作从文件指针开始写入字节并随着对字节的写入而前移此文件指针。写入到文件末尾之后的输出操作导致该数组的扩容。
一、构造函数
RandomAccessFile有两个主要构造函数 RandomAccessFile(File file, String mode)RandomAccessFile(String name, String mode)参数说明 参数 file/name指定要打开的文件可以是一个 File 对象或者一个字符串的文件路径。 参数 mode该参数指定RandomAccessFile的访问模式一共有4种模式
二、功能特点
a. 随机访问 RandomAccessFile 最主要的特点是支持随意访问。与顺序读取的文件类不同RandomAccessFile 允许你跳到文件的任何位置来读写数据。通过文件的指针位置的移动可以实现灵活的操作。
刚打开文件时文件指针指向文件头部。该文件指针可以通过 getFilePointer 方法读取并通过 seek 方法设置。
b. 读写功能并存 它支持文件的读取和写入通过移动文件指针可以在文件的任何位置进行读写。这与其他I/O 输入输出流不同其他流通常是单向的只能顺序读或顺序写。
c. 文件内容修改 它允许修改文件的内容当文件指针处于文件内部时写入数据就可覆盖更新原来的文件内容。也可在文件尾部追加数据。
三、 常用方法
long getFilePointer()获取当前文件指针位置long length()获取文件长度getChannel()返回nio通信的文件通道FileChannelseek(long pos)文件指针定位。参数 pos表示文件指针的位置。pos 从文件的开始位置计算位置 0 表示文件的起始点文件的尾是length()指定的位置。读写文件的方法。读方法read()有很多种重载方法同样地写方法write()也有对应的多种重载方法。
/***读取数据的重载方法***/
read()读取一个字节返回的是 byte 类型数据0 到 255 之间的值如果到达文件末尾则返回 -1。
read(byte[] b)从文件中读取多个字节到字节数组 b 中。
read(byte[] b, int off, int len)可以用来从文件中读取数据到字节数组的指定位置并读取指定的字节数
readInt()、readLong()、readDouble()可以分别读取 4 字节的整数、8 字节的长整数、8 字节的浮点数。/***写入数据的重载方法***/
write(int b)写入一个字节到文件中。
write(byte[] b)将字节数组 b 写入文件。
write(byte[] b, int off, int len)写入部分字节数组。功能将字节数组 b 中从偏移量 off 开始的 len 个字节写入文件。
writeInt(int v)、writeLong(long v)、writeDouble(double v)分别将 4 字节的整数、8 字节的长整数、8 字节的双精度浮点数写入文件。按行读取数据的方法 String readLine()从该文件中读取一行文本。 两个读写UTF-8编码数据文件的方法 a. readUTF()方法从文件读取 UTF-8 编码的字符串。此方法首先读取两个字节的长度信息然后根据这个长度读取字符串的 UTF-8 字节。最后这些字节被转换为 Java 字符串。这意味着当你使用 readUTF 方法读取字符串时需要确保文件中的字符串是使用 writeUTF 方法写入的这样它们之间的长度信息和编码方式才能保持一致。 b. writeUTF(String str)方法将一个字符串以 UTF-8 编码写入文件。此方法首先写入两个字节的长度信息表示字符串的 UTF-8 字节长度然后写入 UTF-8 字节本身。
setLength(long newLength)设置文件长度close()关闭文件
四、RandomAccessFile的使用场景 RandomAccessFile 非常适合以下几种场景
a. 文件分块与合并 你可以利用 seek() 定位文件的任意部分结合 read() 和 write() 方法实现对大文件的分块操作。这种技术通常用于文件上传、下载等场景。
b. 日志文件 对于需要频繁追加数据的日志文件RandomAccessFile 可以方便地在文件末尾写入新日志而不需要重新读取或写入文件的其他部分。
c. 视频流、音频流的处理 在处理大文件如视频、音频时RandomAccessFile 的随机访问功能非常重要因为这些文件通常需要快速定位到某一帧进行处理而不是顺序读取。
五、一个有残疾的文件切割例子 使用RandomAccessFile类读取文件并将文件切割成若干个数据块。 详见参考资料 “如何使用Java语言实现文件分片上传和断点续传功能” 网友的原始代码有BUG问题多多请看其代码
// 创建RandomAccessFile对象
RandomAccessFile raf new RandomAccessFile(file, r);// 计算数据块大小
long blockSize file.length() / numThreads;
if (file.length() % numThreads ! 0) {blockSize;
}// 切割文件并保存到磁盘
for (int i 0; i numThreads; i) {long start i * blockSize;long end Math.min(start blockSize, file.length());byte[] buff new byte[(int) (end - start)];raf.seek(start);raf.read(buff);String path savePath File.separator i .part;try (FileOutputStream fos new FileOutputStream(path)) {fos.write(buff);}
}上面的代码有不少错误我这里指出一处读者可自行分析图中if语句块明显“逻辑错误 ***思维混乱” 编写文件切割程序还是有一点难度的。读者若有兴趣可自行编写一个文件切割程序试试。
随意存取文件例程 下面我们给出一个随意存取文件测试例程演示了文件的读取、中间插入和尾部追加三个功能。完整的实例代码
/**** author QiuGen* description 随意存取文件测试* 例程RandomAccessFileTest.java* date 2024/9/28* ***/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileTest {static String MSG 去年今日此门中人面桃花相映红。人面不知何处去桃花依旧笑春风。;/***从文件读数据信息***/public static void readData(String path) {long pos 0;try (RandomAccessFile rFilenew RandomAccessFile(path, r)){System.out.println(文件指针初始位置rFile.getFilePointer());byte buf[] new byte[8];int num 0;while ((numrFile.read(buf))0) {System.out.print(new String(buf, 0, num));}} catch (IOException e) {e.printStackTrace();}}/***文件中间追加数据信息***/public static void insertData(String path,String inf) {try (RandomAccessFile rFilenew RandomAccessFile(path, rw);FileOutputStream fos new FileOutputStream(D:/tmp);FileInputStream fis new FileInputStream(D:/tmp)){long pos (rFile.length()/4)*2; //计算插入位置rFile.seek(pos); //把文件指针定位到文件中间位置//下面的操作把插入点后面的数据存放到临时文件tmpbyte buf[] new byte[8];int num 0;while ((numrFile.read(buf))0) {//循环读取数据fos.write(buf, 0, num); //数据存入临时文件}/***插入追加数据信息inf***/rFile.seek(pos); //重新定位文件指针到插入点rFile.write(inf.getBytes()); //插入追加数据信息//下面的操作把暂存在临时文件tmp中的数据写回文件中while ((numfis.read(buf))0) {//循环读取数据rFile.write(buf, 0, num); //数据写回文件}} catch (IOException e) {e.printStackTrace();}}/***往文件尾部追加数据***/public static void appendData(String path) {try (RandomAccessFile rFilenew RandomAccessFile(path, rw)){rFile.seek(rFile.length()); //把文件指针定位到文件结尾处rFile.write(MSG.getBytes());} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {String str 陌上花开可缓缓归矣。;String path D:/Temp/测试文件;RandomAccessFileTest.appendData(path); //创建文件RandomAccessFileTest.readData(path); //从文件读数据信息System.out.println(\n***向文件追加数据信息***);RandomAccessFileTest.insertData(path, str);//文件中间追加数据信息RandomAccessFileTest.readData(path); //从文件读数据信息}
}
运行测试结果如下
参考资料
1Java IO流——RandomAccessFile随机读写 2如何使用Java语言实现文件分片上传和断点续传功能 3RandomAccessFile详细总结 4RandomAccessFile详解