Java——RAF

开头:RAF的简单介绍

package raf;

import java.io.RandomAccessFile;

/**
 * java.io.RandomAccessFile
 * RAF是专门用来读写文件数据的API.其基于指针对文件数据进行读写
 * 操作,可以灵活的编译文件数据内容。
 * 创建RAF时可以指定对该文件的权限,常用的有两种:
 * r:只读模式
 * rw:读写模式
 * 对当前目录中的raf.dat文件读写
 * RAF支持两种常用构造方法:
 * RandomAccessFile(File file, String mode)
 * RandomAccessFile(String path, String mode)
 * 
 * 注:相对路径中"./"是可以忽略不写的,因为
 * 默认就是从当前目录开始。
 * 
 * RAF创建时含有写权限的情况下,当指定文件
 * 不存在时会自动将其创建出来
 * @author 13651
 *
 */
public class RafDemo {
	public static void main(String[] args) throws Throwable {
		RandomAccessFile raf = new RandomAccessFile("raf.dat", "rw");
		/**
		 * void write(int d)
		 * 向文件中写入1字节,写的是给定int值
		 * 对应2进制的“低八位”
		 * 							  vvvvvvvv
		 * 00000000 00000000 00000000 00000001
		 */
		raf.write(256);
		System.out.println("写出完毕!");
		raf.close();
	}
}

RAF读写基本类型数据,以及RAF的指针操作:
注意:RandomAccessFile read总是在指针当前位置读或写,不管是读还是写,指针都会自动往后移一下

package raf;

import java.io.RandomAccessFile;
/**
 * RAF读写基本类型数据,以及RAF的指针操作
 * 
 * @author 13651
 *
 */
public class RafDemo2 {

	public static void main(String[] args) throws Throwable {
		RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");
		//写入一个int最大值到文件中
		int max = Integer.MAX_VALUE;
		
		long pos = raf.getFilePointer();
		System.out.println(pos);
		/**
		 * int最大值的2进制形式:
		 * 							  vvvvvvvv
		 * 01111111 11111111 11111111 11111111
		 */
		raf.write(max>>>24);
		pos = raf.getFilePointer();

		System.out.println(pos);//1
		raf.seek(pos);
		//RandomAccessFile read总是在指针当前位置读或写,不管是读还是写,
		//指针都会自动往后移一下
		raf.readInt();
		raf.write(max>>>16);
		pos = raf.getFilePointer();

		System.out.println(pos);//2
		
		raf.write(max>>>8);
		pos = raf.getFilePointer();

		System.out.println(pos);//3
		raf.write(max);
		pos = raf.getFilePointer();
		System.out.println("!!");
		
		System.out.println(pos);//4
		/*
		 * void writeInt(int d)
		 * 连续写出4个字节,将给定的int值写出。
		 * 等同上面4次write方法。
		 * void seek(position)指针的滑动,括号内为指定指针的位置
		 * 
		 */
		raf.writeInt(max);
		pos = raf.getFilePointer();
	
		System.out.println(pos);//8
		raf.writeLong(123L);
		raf.seek(8);//读之前必须把指针移动到读取字节之前,
		//不然会抛出EFOException异常
		long l = raf.readLong();
		System.out.println(l);
		pos = raf.getFilePointer();

		System.out.println(pos);//16
		raf.writeDouble(123.123);

		pos = raf.getFilePointer();
		raf.seek(pos);//读之前必须把指针移动到读取字节之前,不然会
		//抛出EFOException异常
		double d =  raf.readDouble();
		System.out.println(d);
		System.out.println(pos);//24
		//运行到这,文件有24个字节,4+4+8+8
		System.out.println("写入完毕!");
		
		
		raf.close();
	}
}

注意指针的移动语句seek()位置的影响

package day04;

import java.io.RandomAccessFile;

/**
 * 创建一个"raf.dat"的文件,并在其中写出一个int的最大值,long的最大值,
 * 然后将其分别读取出来并输出
 * @author Admin
 *
 */
public class Test01 {
	public static void main(String[] args) throws Throwable {
		RandomAccessFile raf = new RandomAccessFile("raf.dat", "rw");
		long pos = raf.getFilePointer();
		int max = Integer.MAX_VALUE;
		
		raf.writeInt(max);
		raf.seek(pos);
		System.out.println(raf.readInt());
		long lMax = Long.MAX_VALUE;
		pos = raf.getFilePointer();//获取文件指针必须要在write之前,
		//否则会Console会有EFOException异常
		raf.writeLong(lMax);
		raf.seek(pos);//读之前必须把指针移动到读取字节之前,
		//不然会抛出EFOException异常
		System.out.println(raf.readLong());		
		raf.close();
	}
}

中间:RAF的读操作

package raf;


import java.io.RandomAccessFile;
/**
 * 读取文件数据
 * @author 13651
 *
 */
public class ReadDemo {

	public static void main(String[] args) throws Throwable {
		/**
		 * 读取当前目录中raf.dat文件内容
		 */
	RandomAccessFile raf = new RandomAccessFile("raf.dat","rw");
		/**
		 * int read()
		 * 读取一个字节,并以int形式返回。
		 * 若返回值为-1则表示读取到文件末尾。
		 * 八位二进制,写入-1,读出为255.
		 * 无论输入啥,对256取模就是结果。
		 */
		int d =raf.read();
		System.out.println(d);
		raf.close();
	}

}

结尾:RAF的复制
1.高效率复制,块复制:

package raf;


import java.io.RandomAccessFile;


/**
 * 若希望提高读写效率,可以通过提高每次实际读写的数据量,
 * 减少实际发生的读写操作来做到。
 * 单字节读写:随机读写
 * 一组字节读写:块读写
 * 机械硬盘(磁盘)的块读写效率还是比较好的。但是
 * 随机读写效率极差。
 * @author 13651
 *
 */
public class CopyDemo2 {

	public static void main(String[] args) throws Throwable {
		RandomAccessFile src = new RandomAccessFile("momi.msi", "r");
		RandomAccessFile desc = new RandomAccessFile("vmvm.msi","rw");
		/*
		 * RAF提供的块读写操作的方法:
		 * int read(byte[] data)
		 * 一次性读取给定字节数组长度的字节
		 * 量并存入到该数组中。返回值为实际
		 * 读取到的字节量,若返回值为-1,表示
		 * 本次读取的是文件末尾(没读到任何字节)
		 * 
		 * void write(byte[] data)
		 * 一次性写出给定字节数组中的所有字节
		 */
		//记录每次实际读取到的字节量
		int len = -1;
		//每次要求读取的字节量
		//10kb
		byte[] data = new byte[1024*10];
		long starts = System.currentTimeMillis();
		while((len = src.read(data))!=-1) {
			desc.write(data, 0, len);
		}
		long end = System.currentTimeMillis();
		System.out.println("复制完毕:"+(end-starts)+"ms");//复制完毕:1500ms
		src.close();
		desc.close();
	}
		

}

2.一般复制(一般不用)

package raf;


import java.io.RandomAccessFile;

/**
 * 复制文件
 * @author 13651
 *
 */
public class CopyDemo {

	public static void main(String[] args) throws Throwable {
		/**
		 * 创建两个RAF,一个用来读原文件,一个用来往复制文件中写
		 * 。顺序从原文件读取每个字节写到复制文件中。
		 */
		RandomAccessFile src = new RandomAccessFile("12.png", "r");
		RandomAccessFile desc = new RandomAccessFile("22.png", "rw");
		int d = -1;
		while((d = src.read())!=1) {
			desc.write(d);
		}
		System.out.println("复制完毕!");
		src.close();
		desc.close();
	}

}

写文件与读文件:

package raf;

 
import java.io.RandomAccessFile;
/**
 * 写文件
 * @author 13651
 *
 */
public class StringWriteDemo {

	public static void main(String[] args) throws Throwable {
		RandomAccessFile raf = new RandomAccessFile("test.txt","rw");
		String line = "愉快的代码人";
		/*
		 * String 提供了一个转换为二进制的方法
		 * byte[] getByte();
		 */
		//可以指定字符集进行转换
		byte[] data = line.getBytes("UTF-8");
		raf.write(data);
		System.out.println("写入完毕!");
		raf.close();
	}

}

package raf;

import java.io.RandomAccessFile;

/**
 * 读文件
 * @author 13651
 *
 */
public class StringReadDemo {

	public static void main(String[] args) throws Throwable {
		RandomAccessFile raf = new RandomAccessFile("test.txt", "r");
		/*
		 * 
		 */
		byte[] data = new byte[(int)raf.length()];
		raf.read(data);
		String read = new String(data,"UTF-8");
		System.out.println(read);
		raf.close();
	}

}

小测试:完成用户注册系统

package raf;

import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Scanner;


/**
 * 完成用户注册系统
 * 
 * 程序开始后,要求用户输入:
 * 用户名,密码,昵称,年龄
 * 
 * 将该记录写入到user.dat文件中。
 * 其中用户名,密码,昵称为字符串。年龄为
 * 一个int值。
 * 
 * 每条记录占有100字节,其中:用户名,密码,
 * 昵称为字符串,各占32字节,年龄为int占用
 * 4字节。
 * 
 * @author 13651
 *
 */
public class RegDemo {

	public static void main(String[] args) throws Throwable {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入用户名");
		String name = sc.nextLine();
		System.out.println("请输入密码:");
		String password = sc.nextLine();
		System.out.println("请输入昵称:");
		String nickName = sc.nextLine();
		System.out.println("年龄:");
		int age = sc.nextInt();
		System.out.println(name+","+password+","+nickName+","+age);
		RandomAccessFile raf = new RandomAccessFile("user.dat", "rw");
		//先讲指针移动到文件末尾
		raf.seek(raf.length());
		//1先将用户名转成对应的一组字节
		byte[] data = name.getBytes("UTF-8");
		//2将数组进行扩容
		data = Arrays.copyOf(data,32);
		//3将该字节数组一次性写入文件
		raf.write(data);
		//写密码
		data = password.getBytes("UTF-8");
		data = Arrays.copyOf(data, 32);
		raf.write(data);
		//写昵称
		data = nickName.getBytes();
		data = Arrays.copyOf(data, 32);
		raf.write(data);
		//写年龄
		raf.writeInt(age);
		System.out.println("写入完毕!");
		raf.close();
		sc.close();
	}

}

显示用户的信息,这边需要注意

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Scanner;

/**
 * 显示用户信息
 * @author 13651
 *
 */
public class ShowAllUseDemo {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		System.out.println("用户输入用户名:");
		String name = sc.nextLine(); 
		System.out.println("用户输入新昵称:");
		String nickName = sc.nextLine();
		RandomAccessFile raf = new RandomAccessFile("user.dat", "rw");
		/*
		 * 循环显示若干个100字节
		 */
		boolean flag = false;
		for (int i = 0; i < raf.length()/100; i++) {
			byte[] data = new byte[32];
			//移动指针
			raf.seek(i*100);
			//将32个字节读入
			raf.read(data);
			//将字节数组转换为字符串
			String username = new String(data,"UTF-8").trim();
			
			raf.read(data);
			String password = new String(data,"UTF-8").trim();
		
			raf.read(data);
			String nickname = new String(data,"UTF-8").trim();
			
			int age = raf.readInt();
			
			System.out.println(username+","+password+","+nickname+","+age);
		
			if(name.equals(username)) {
				raf.seek(i*100+64);
				//获取新的用户名
				data = nickName.getBytes("UTF-8");//46条语句
				data = Arrays.copyOf(data, 32);//为什么上面有data,
				//还是需要扩容呢?因为data只是变量,第46条语句是获取新的
				//用户名称,因此重新扩容
				raf.write(data);
				System.out.println("修改完毕!");
				flag = true;
				break;
			}else {
				continue;
			}
		}
		if(!flag) {
			System.out.println("无此用户");
		}
		raf.close();
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值