RandomAccessFile
1、RandomAccessFIle 类的读写是基于指针的操作,该类可以对文件进行随机访问操作,包括读写操作。
1.1、字节数据读写操作
void write(int d) 方法,根据当前指针位置写入一个字节,是将 int 的“低8位”(二进制位)写出。
File file = new File("/home/soft01/demo/wei.txt"); if(!file.exists())file.createNewFile(); RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");//第二个参数“rw”是读写,“r”是只读,“w”是只写 //字符的unico码小,用一个byte就可以传输了 randomAccessFile.write(0x41);//A randomAccessFile.write(0x42);//B //下面三行合起来是一个 “中” 字 randomAccessFile.write(0xe4); randomAccessFile.write(0xb8); randomAccessFile.write(0xad); randomAccessFile.close();
int read()方法,从文件中读取一个byte(8位)填充到int的低8位,高24位为0(int型是32位),返回值范围正数:0~255,如果返回-1表示读取到文件末尾。该方法每次读取后会自动移动指针,准备下次读取。
下面例子实现文件复制
RandomAccessFile read = new RandomAccessFile("/home/soft01/demo/test.txt","r");//要复制的文件 RandomAccessFile write = new RandomAccessFile("/home/soft01/demo/test副本.txt","rw"); int num = -1; while((num = read.read()) != -1) {//当读取到-1表示读到了文件末尾,退出循环 write.write(num);//写入读取到的数据,num的低8位,一个字节 } read.close(); write.close(); System.out.println("文件复制成功");
上面例子是一个字节一个字节地复制的,所以复制速度比较慢,如果想让复制速度加快,可以使用缓冲流。
下面例子每次读写1KB
RandomAccessFile read = new RandomAccessFile("/home/soft01/demo/test.txt","r");//要复制的文件 RandomAccessFile write = new RandomAccessFile("/home/soft01/demo/test副本2.txt","rw"); int len = -1; byte[]data = new byte[1024];//1KB while((len = read.read(data)) != -1) {//读取数据并返回读取到的长度,当读取到-1表示读到了文件末尾,退出循环 write.write(data,0,len);//写入有效数据 } read.close(); write.close(); System.out.println("文件复制成功");
保存用户信息(每个用户的信息用100字节保存)
String username = "苏东坡"; String password = "123456"; int age = 20; String gender = "男"; String email = "sdp@163.com"; RandomAccessFile randomAccessFile = new RandomAccessFile("/home/soft01/demo/user.style","rw"); randomAccessFile.seek(randomAccessFile.length());//将指针移动到文件末尾 byte[]data = username.getBytes("utf-8");//以UTF-8编码将用户名转换成byte数组 data = Arrays.copyOf(data, 30);//设置为30字节,用30字节保存用户名 randomAccessFile.write(data);//将byte数组写入文件 data = password.getBytes("utf-8"); data = Arrays.copyOf(data, 30);//用30字节保存密码 randomAccessFile.write(data); randomAccessFile.writeInt(age);//整型4个字节 data = gender.getBytes("utf-8"); randomAccessFile.write(data);//3字节,这里中文为3字节,英文就是2字节 data = email.getBytes("utf-8"); data = Arrays.copyOf(data,33);//Email用33字节保存 randomAccessFile.write(data); System.out.println("游标位置:"+randomAccessFile.getFilePointer());//输出指针位置 //写入第二个用户信息 username = "貂蝉"; data = username.getBytes("utf-8");//以UTF-8编码将用户名转换成byte数组 data = Arrays.copyOf(data, 30);//设置为30字节,用30字节保存用户名 randomAccessFile.write(data);//将byte数组写入文件 data = password.getBytes("utf-8"); data = Arrays.copyOf(data, 30);//用30字节保存密码 randomAccessFile.write(data); randomAccessFile.writeInt(age);//整型4个字节 gender = "女"; data = gender.getBytes("utf-8"); randomAccessFile.write(data);//3字节,这里中文为3字节,英文就是2字节 email = "dc@qq.com"; data = email.getBytes("utf-8"); data = Arrays.copyOf(data,33);//Email用33字节保存 randomAccessFile.write(data); System.out.println("游标位置:"+randomAccessFile.getFilePointer()); randomAccessFile.close(); System.out.println("用户信息保存完毕!");
上面例子也可以使用 writebytes(String str)写入,但是这样就不能指定字符集编码了。
读取用户信息
/** * 每个用户的信息都是占用100字节 */ RandomAccessFile randomAccessFile = new RandomAccessFile("/home/soft01/demo/user.style","rw"); for(int i =0;i<randomAccessFile.length()/100;i++) { byte[] data = new byte[30]; randomAccessFile.read(data);//读取30字节(用户名) String username = new String(data,"utf-8").trim(); //将读取到的byte数组以“utf-8”格式转成String,并去除空格 //因为保存时每个用户名都扩展为30字节保存,用户名后面会用空格填充,所以必须去除空格 randomAccessFile.read(data); String password = new String(data,"utf-8").trim(); int age = randomAccessFile.readInt(); data = new byte[3]; randomAccessFile.read(data); String sex = new String(data,"utf-8"); data = new byte[33]; randomAccessFile.read(data); String email = new String(data,"utf-8").trim(); System.out.println("姓名:"+username+" , 用户密码:"+password+" , 年龄:"+age +" , 性别:"+sex+" , 邮箱:"+email); } randomAccessFile.seek(100);//移动指针到第二个用户那 byte[] data = new byte[30]; randomAccessFile.read(data);//读取30字节 System.out.println("第二个用户的名字为:"+new String(data,"utf-8"));
用户登陆操作
public static boolean login(String name,String pwd) {//登陆成功返回true,否则返回false try { RandomAccessFile randomAccessFile = new RandomAccessFile("/home/soft01/demo/user.style","r"); byte[] data = new byte[30]; Scanner sc = new Scanner(System.in); for(int i=0;i<randomAccessFile.length()/100;i++) { randomAccessFile.seek(i*100);//指向第i个用户 randomAccessFile.read(data); if(new String(data,"utf-8").trim().equalsIgnoreCase(name)){ randomAccessFile.read(data); if(new String(data,"utf-8").trim().equalsIgnoreCase(pwd)) { return true; } } } }catch(IOException e) { System.out.println(e.getMessage()); } return false; }