Java:RandomAccessFile类:文件内容的读写访问操作

RandomAccessFile类是java提供的对文件内容的访问类,既可以读文件,也可以写文件。

RandomAccessFile类支持随机访问文件,也就是可以访问文件的任意位置。

(1)java的文件模型

在硬盘上的文件是以byte存储的,是数据的集合

(2)打开文件有两种模式

 “rw”(读写)    可以对文件进行读写

“r”(只读)    只能对文件进行读操作

代码示例:RandomAccessFile raf = new RandomeAccessFile(file,"rw")

文件指针,打开文件的时候指针在开头 pointer=0;

(3)写方法

raf.write(int)--一次只能写一个字节(后8位),传入一个int类型,那么需要进行4次写操作写完后指针指向下一个位置,准备再次写入

(4)读方法 

int b=raf.read()-----在指针在的位置读一个字节,然后把该字节操作成整数

(5)文件读写完一定要记得关闭io流(来自Oracle的官方警告)

具体代码示例:

package demo2;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.RandomAccess;

public class RafDemo {

	public static void main(String[] args) throws IOException {
		// 在内存中创建文件对象
		File demo = new File("demo");// 不填路径则默认在工程文件夹下创建
		// 如果文件(夹)不存在则创建文件(夹)
		if (!demo.exists()) {
			// 创建文件夹
			demo.mkdir();
		}
		// 以demo文件夹作为父目录,创建一个raf.dat文件
		File file = new File(demo, "raf.dat");
		if (!file.exists()) {
			// 不存在则创建
			file.createNewFile();
		}
		// 进行读写操作

		// 指定要读写的对象与选择读写模式
		RandomAccessFile raf = new RandomAccessFile(file, "rw");
		// 查看指针位置
		System.out.println("第1次查看指针位置" + "前面有" + raf.getFilePointer() + "个字符");
		// write一次只能写1个字节,所以只会将A的低八位写进去
		raf.write('A');// 只写了一个字节进去
		// 查看指针位置
		System.out.println("第2次查看指针位置" + "前面有" + raf.getFilePointer() + "个字符");
		raf.write('B');
		// 将i写进去
		System.out.println("第3次查看指针位置" + "前面有" + raf.getFilePointer() + "个字符");
		int i = 0x7fffffff;
		// 用write方法每次只能写一个字节,int是4个字节也就是32位,则要写四次
		// 右移24位,则高八位变成低八位,就可以将高位写进去,如果看不懂这,可以先去看看二进制相关知识。

		raf.write(i >>> 24);
		raf.write(i >>> 16);
		raf.write(i >>> 8);
		raf.write(i);
		System.out.println("第4次指针位置:" + "前面有" + raf.getFilePointer() + "个字符");
		// 其实也有相应的方法可以直接写入int,上面的位移写入是他的底层原理
		raf.writeInt(i);
		// 尝试写入中文
		String s = "中";// 在用输入法打出这个字符串的时候是使用java默认的utf-16be编码

		//
		byte[] gbk = s.getBytes("GBK");// 在这将其转换为gbk编码
		raf.write(gbk);
		// 查看文件长度
		System.out.println("文件长度为" + raf.length() + "字节");
		/*
		 * Java是双字节编码,采用的是utf-16be编码方式,
		 * 
		 * 这里的write()写入A、B、i 都是采用的Java默认的utf-16be编码,
		 * 
		 * 而utf-16be编码是中文和英文都占两个字节。
		 * 
		 * 也就是A,B传进去之前是char型16位,本身是占两个字节,但每次只能传低八位进去,所以只传进去2个字节
		 * 
		 * 又因为大小写字母在编码表中对应的编码都在byte类型范围内,所以不需要进行位移都可以完整传进去
		 * 
		 * 而是整形,需要完整将i传进去需要传4次,每次以整形4个字节传进去,但每次只传进1个字节(低8位),所以i占了4个字节
		 * 
		 * 后面的汉字“中”采用的gbk编码方式是中文占两个字节,英文占1个字节。所以“中”占用了2个字节
		 * 
		 * 所以getBytes("gbk")指定了编码方式。
		 * 
		 * 因为在文件的(手动查看)编码方式中char字符占2个字节,
		 * 
		 * 所以A占2个字节,B占2个字节,int类的i占4字节,中占2字节,
		 *
		 * 所以文件长度为12个字节
		 */

		// 完整读取文件时必须从文件开始读取,也就是要将指针移到头部
		raf.seek(0);
		// 一次性读取,将读取到的内容都存储到字节数组中

		// raf.length()返回的是long类型

		// 创建byte数组来储存读取到的内容,数组长度由将要读取的文件长度决定
		byte[] buf = new byte[(int) raf.length()];

		// 从该文件读取最多数组长度个字节的数据到该字节数组。
		raf.read(buf);

		System.out.println(Arrays.toString(buf));
		// 使用指定的编码将buf数组转换为字符串的形式输出,
		String s1 = new String(buf, "GBK");

		System.out.println(s1);// 输出结果出现乱码
		/*
		 * 读取的时候是!整个!文件读取出来,
		 * 
		 * 其中int类的i分开四个写,
		 * 
		 * 所以计算机没法找到对应的编码,所以乱码了
		 */
		// 以16进制输出
		for (byte b : buf) {
			System.out.print(Integer.toHexString(b & 0xff) + " ");
		}
		// 关闭文件io流,务必!
		raf.close();
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值