JAVA中RandomAccessFile

JAVA中RandomAccessFile

一.RandomAccessFile的基本介绍:

RandomAccessFile

  • 该类基于指针用来读写文件数据
  • 创建RandomAccessFile常用的构造方法:
  • RandomAccessFile(String path,String mode)
  • RandomAccessFile(File file,string mode)
  • 第一个参数是要进行读写的文件
  • 第二个参数为权限
  • r:只读模式 例如: RandomAccessFile raf=new RandomAccessFile(file, “r”);
  • rw:读写模式 例如:RandomAccessFile raff=new RandomAccessFile(“demo2.txt”, “rw”);

二:RandomAccessFile的读写操作

1.写:

1.创建 RandomAccessFile文件,向文件中写入a。

public class RandomAccessFileWriteDemo {
	public static void main(String[] args) throws IOException {
		//方式一:RandomAccessFile(String path,String mode)
//		File file=new File("./demo");
//		RandomAccessFile raf=new RandomAccessFile(file, "r");
//		System.out.println("执行完毕");
		
		//方式二:RandomAccessFile(File file,string mode)
		RandomAccessFile raff=new RandomAccessFile("demo2.txt", "rw");
		System.out.println("执行完毕!");
		
		/*
		 * RandomAccessFile提供了void write(int d),
		 * 向文件中写入一个字节数据,写的是给定int值所对应的二进制的”低八位“
		 * 000000000 00000000 00000000 00000001
		 * 
		 * 例如:97转为二进制11000011,由于常用编译器会在开的时候,
		 * 将字节显示,查询ASCII编码,会显示a,其他值则查询系统默认的码
		 */
		
		raff.write(65);
		System.out.println("写入完毕!");
		
		/*
		 * RandomAccessFile在文件访问的操作全部结束的时候,要调用close()方法来
		 * 释放所有系统资源
		 */
		
		raff.close();
	}
}

2.设置指针位置;

RandomAccessFile提供了一个方法seek(int n),设置指针位置.

RandomAccessFile提供了一个方法getFilePointer(),获取指针位置.

public class RandomAccessFileWriteDemo2 {
	public static void main(String[] args) throws IOException {
		String str="hello";
		//将字符串转换为字节
		byte[] b=str.getBytes();
		RandomAccessFile raff=new RandomAccessFile("demo.txt", "rw");
		//设置指针位置,RAF提供了获取指针位置的方法seek()
		raff.seek(10);//设置指针位置5,追加字符串world
		//获取指针的位置(游标位置)RAF提供了获取指针位置的方法getFilePointer()返回long
		long p=raff.getFilePointer();
		System.out.println("写入前的位置:"+p);//10
		raff.write(b);
		System.out.println("写入完毕!!!!");
		p=raff.getFilePointer();//15
		System.out.println("写入后的指针位置:"+p);
		raff.close();
	}
}

3.字符集;

  • 按照系统默认字符集转换(不推荐,因为存在平台差异)
  • byte[] getBytes(String scan) scan:字符集
  • 按照给定的字符集转换,字符集的名字不区分大小写;
  • GBK:国际编码,中文占2个字节
  • UTF-8:也称万国码,中文占3个字节
  • ISO8859-1:欧洲字符集,不支持中文。
public class RandomAccessFileWriteDemo3 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("demo2.txt", "rw");
		String str="你好,树先生";
		byte[] b=str.getBytes("UTF-8");//将字符串转换为字节
		System.out.println(b.length);//18
		raf.write(b);
		System.out.println("输入完毕!!");
		raf.close();
	}
}
2.读:

1.使用RandomAccessFile读取文件中的数据(字节读取);

RandomAccessFile提供了read()方法,返回int。

public class RandomAccessFileReadDemo {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("demo.txt","r");
		int len=-1;//保存读取到的每一个字节
		while((len=raf.read())!=-1){//数据读到-1时则读到文件的末尾
			System.out.print((char)len);
		}
		raf.close();
	}
}

2.块读取一:

public class RandomAccessFileReadDemo2 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("demo2.txt", "r");
		byte[] bs=new byte[100];
		int n=raf.read(bs);//读取100个字节并存放在bs字节数组中,返回的是实际读到的字节数据量
		System.out.println(n);
		//把读取出来的字节转换为字符串
		String str=new String(bs,"gbk");
		System.out.println(str);
		raf.close();
	}
}

该读取的弊端是读取出来的字符串长度是100,浪费空间大小。

3.块读取二:

string有构造方法string(byte[] b,int offset,int len ,string scn);

将给定的字节数组从下标offset连续读取len个。

public class RandomAccessFileReadDemo3 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("demo2.txt","r");
		byte[] bs=new byte[100];
		int len=raf.read(bs);
		System.out.println(len);
		String str=new String(bs,0,len,"UTF-8");
		System.out.println(str);
		raf.close();
	}
}

这种读取快,并且读到的是字符串真实的长度,不会浪费内存空间。

三.用RandomAccessFile进行MP3的复制

1.使用指针读写
public class RandomAccessFile_copyMP3Demo {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf_r=new  RandomAccessFile("D:/CloudMusic/Against the Current - Legends Never Die.mp3","r");
		RandomAccessFile raf_w=new RandomAccessFile("D:/CloudMusic/复制后的Against the Current - Legends Never Die.mp3","rw");
		long time1=System.currentTimeMillis();//获取当前时间的毫秒数
		System.out.println("正在复制中....");
		int len=-1;
		while((len=raf_r.read())!=-1){
			raf_w.write(len);
		}
		
		long time2=System.currentTimeMillis();//获取当前时间的毫秒数
		System.out.println("复制所需要的毫秒数"+(time2-time1)/1000+"秒");
		
		raf_r.close();
		raf_w.close();
		
	}
}
2.使用块读写
public class RandomAccessFile_copyMP3Demo2 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf_r=new RandomAccessFile("D:/CloudMusic/Against the Current - Legends Never Die.mp3", "r");
		RandomAccessFile raf_w=new RandomAccessFile("D:/CloudMusic/复制第3次后的Against the Current - Legends Never Die.mp3", "rw");
		byte[] bs=new byte[1024*10];
		int len=-1;
		long p1=System.currentTimeMillis();
		System.out.println("正在复制。。");
		while((len=raf_r.read(bs))!=-1){
			raf_w.write(bs,0,len);
		}
		System.out.println("复制完成。。");
		long p2=System.currentTimeMillis();
		System.out.println("复制时间为:"+(p2-p1));
		raf_r.close();
		raf_w.close();
	}
}
结论:

由于硬盘的物理性,导致随机读写效率很低,因此我们推荐“块读写”;

块读写的效率很高,一次一组字节读写数据,所以若想着读写效率我们需要提高每次

读写的次数.

四.使用RandomAccessFile模拟数据库,进行增查改操作。

1.完成用户注册
  • 用uer.dat文件保存用户信息
  • 每个用户信息包括:用户名,密码,昵称,年龄
  • 其中年龄用int类行,其他是字符串类型
public class RandomAccessFile_userRegister {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("user.dat","rw");
		raf.seek(raf.length());//设置指针位置
		Scanner scanner=new Scanner(System.in);
		String name=scanner.next();
		String pwd=scanner.next();
		String nick=scanner.next();
		int age=scanner.nextInt();
		
		//对数组进行扩容写入用户名
		byte[] data=name.getBytes("UTF-8");
		data=Arrays.copyOf(data,32);
		raf.write(data);
		
		
		//对数组进行扩容写入密码
		data=pwd.getBytes();
		data=Arrays.copyOf(data,32);
		raf.write(data);
		
		//对数组进行扩容写入昵称
		data=nick.getBytes("UTF-8");
		data=Arrays.copyOf(data,32);
		raf.write(data);
		
		//年龄
		raf.writeInt(age);
		
		System.out.println("写入完毕!!");
		System.out.println(raf.getFilePointer());

		//raf.close();
	}
}
2.用户登录功能

如果登录成功显示该用户的所有信息;

public class RandomAccessFileUserlogin {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("demo5.txt","r");
		Scanner scanner=new Scanner(System.in);
		System.out.println("账号输入:");
		String user_name=scanner.next();
		System.out.println("输入密码:");
		String user_pwd=scanner.next();
		byte[] bs=new byte[32];
		boolean nameflag=false;
		boolean pwdflag=false;
		for(int i=0;i<raf.length()/100;i++){
			raf.seek(i*100);//设置指针位置
			System.out.println("指针位置:"+raf.getFilePointer());
			raf.read(bs);//获取姓名
			String name=new String(bs,"UTF-8").trim();
			if(name.equals(user_name)){
				System.out.println("账号正确!");
				nameflag=true;
				raf.read(bs);//获取密码
				String pwd=new String(bs,"UTF-8").trim();
				if(pwd.equals(user_pwd)){
					System.out.println("密码输入正确!");
					pwdflag=true;
					System.out.println("登录成功!!");
					raf.read(bs);//获取昵称
					String nick=new String(bs,"utf-8");
					int age=raf.readInt();
					System.out.println("输出用户信息为"+name+","+pwd+","+nick+","+age);
				}
				break;
			}
		}
		if(nameflag==false){
			System.out.println("账号错误");
			return;
		}
		if(pwdflag==false){
			System.out.println("密码错误");
		}
	}
}
3.修改用户数据密码

前提是登陆成功才可以修改;

public class RandomAccessFileUserupdate {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("demo9.txt","rw");
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入名字:");
		String user_name=scanner.next();
		System.out.println("请输入密码:");
		String user_pwd=scanner.next();
		byte[] data=new byte[32];
		boolean nameflag=false;
		boolean pwdflag=false;
		for(int i=0;i<raf.length()/100;i++){
			raf.seek(i*100);//设置指针位置
			raf.read(data);//读取名字
			String name=new String(data,"UTF-8").trim();
			if(name.equals(user_name)){
				System.out.println("用户名正确!");
				nameflag=true;
				raf.read(data);//读取密码
				String pwd=new String(data,"UTF-8").trim();
				if(pwd.equals(user_pwd)){
					System.out.println("密码正确!!");
					pwdflag=true;
					System.out.println("密码修改:");
					String newpwd=scanner.next();
					raf.seek(i*100+32);//或者raf.seek(raf.getFilePointer()-32);
					byte[] bs=newpwd.getBytes("UTF-8");
					bs=Arrays.copyOf(bs,32);
					raf.write(bs);//将新密码写入
					System.out.println("密码修改成功!!!");
				}
				break;
			}
		}
		if(nameflag==false){
			System.out.println("用户名错误!");
			return;
		}
		
		if(pwdflag==false){
			System.out.println("密码错误!");
		}
	}
}
4.读取所有用户的数据

将读取出来的用户数据以格式name,pwd,nick,age输出;

public class RandomAccessFile_userRead {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf=new RandomAccessFile("user.dat","r");
		byte[] bs=new byte[32];
		for(int i=0;i<raf.length()/100;i++){
			raf.read(bs);
			//获取名字
			String name=new String(bs,"utf-8").trim();
			
			//读取密码
			raf.read(bs);
			String pwd=new String(bs,"utf-8").trim();
			
			//获取昵称
			raf.read(bs);
			String nick=new String(bs,"utf-8").trim();
			
			//读取年龄
			int ag=raf.readInt();//读取到int类型4字节
			System.out.println(name +"   "+pwd+"  "+nick+"   "+ag);
			System.out.println(raf.getFilePointer());//获取指针位置
		}
		raf.close();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值