IO非流:RandomAccessFile(Java SE第三阶段4)

目录

RAF

向文件中写入一个字节

从文件中读取一个字节

单字节读写复制文件

块读写复制文件

块写

块读

基于指针的读写操作

练习:用户团建

练习:读取团建用户信息

练习:修改团建用户信息

练习:完成简易记事本工具



RAF


向文件中写入一个字节

java.io.RandomAccessFile RAF是专门用来读写文件数据的类,其基于指针对文件数据随机读写。

/**
         * 常用构造器
         * RandomAccessFile(String path, String mode)
         * RandomAccessFile(File file, String mode)
         * 
         * mode为操作权限: r为只读模式,rw为读写模式。
         * 
         */

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;
public class RAFDemo1 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf = new RandomAccessFile("./raf.dat","rw");
		/**
		 * void write(int d)
		 * 向文件中写入一个字节,写入的是给定的int值(4个字节32位)对应的2进制的"低八位",0000 0001
		 */
		raf.write(1);// 第一个字节
		raf.write(2);// 第二个字节
		System.out.println("写出完毕!");
		raf.close();
	}
}

从文件中读取一个字节

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;
public class RAFDemo2 {

	public static void main(String[] args) throws IOException {
		RandomAccessFile raf = new RandomAccessFile("raf.dat","r");
		/**
		 * int read()  从文件中读取一个字节,并以int型返回。若返回值为-1,则表示文件末尾。
		 * 因为写的是低八位,返回的int型,会自动补3个字节,前面补24个0.
		 */
		int d = raf.read();// 读第一个字节1
		System.out.println(d);
		
		d = raf.read(); // 读第一个字节2
		System.out.println(d);
		
		d = raf.read(); // 末尾返回-1
		System.out.println(d);
		
		raf.close();
	}

}

单字节读写复制文件

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

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

	public static void main(String[] args) throws IOException {
		RandomAccessFile src = new RandomAccessFile("1.jpg", "r");
		RandomAccessFile desc = new RandomAccessFile("1_cp.jpg", "rw");

		int d = -1;// 记录每次读取到的字节
		long start = System.currentTimeMillis();
		while ((d = src.read()) != -1) {
			desc.write(d);
		}
		long end = System.currentTimeMillis();
		System.out.println("复制完毕!耗时" + (end - start) + "ms");
		src.close();
		desc.close();
	}

}

块读写复制文件

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 通过提高每次实际读写的数据量,减少实际读写的次数可以提高读写效率。
 * 单字节读写是随机读写.
 * 一组字节读写是块读写。
 * 
 * void write(byte[] data) 一次性将给定的字节数组中所有字节写出。
 * void write(byte[] data, int i, int len) 将给定数组中从下标i处的连续len个字节一次性写出。
 * @author Jack
 *
 */
public class CopyDemo2 {
	public static void main(String[] args) throws IOException {
		RandomAccessFile src = new RandomAccessFile("1.jpg", "r");
		RandomAccessFile desc = new RandomAccessFile("1_cp.jpg", "rw");
		
		/**
		 * int read(byte[] data)
		 * 一次性读取给定的字节数组总长度的字节量并存入该数组中,返回值为本次实际读取到的字节量。
		 * 若返回值为-1,则表示本次读取时已经是文件末尾。
		 */
		int len = -1;// 每次实际读写的字节数
		byte[] data = new byte[1024*10];// 每次读入10k
		
		long start = System.currentTimeMillis();
		while((len=src.read(data))!=-1) {
			desc.write(data,0,len);
		}
		long end = System.currentTimeMillis();
		System.out.println("复制完毕!耗时"+ (end - start) + "ms");
		src.close();
		desc.close();
	}
}

块写

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 写出文本数据
 * 
 * @author Jack
 *
 */
public class WriteStringDemo {
	public static void main(String[] args) throws IOException {
		RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
		/**
		 * String 提供了转换为字节的方法:
		 * byte[] getBytes(String csn) 将当前字符串按照指定的字符集转换为字节。
 		 */
		String line = "康康,where are you from ? ";
		byte[] data = line.getBytes("utf-8");
		
		raf.write(data);
		System.out.println("写出完毕!");
		raf.close();
	}
}

块读

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读取文本数据
 * 
 * @author Jack
 *
 */
public class ReadStringDemo {

	public static void main(String[] args) throws IOException {
		RandomAccessFile raf = new RandomAccessFile("raf.txt", "r");

		byte[] data = new byte[(int) raf.length()];// 
		raf.read(data);
		
		/**
		 * String 提供了将字节还原为字符串的构造方法:
		 * String(byte[] data, String csn)
		 * 将给定的字节数组按照指定的字符集还原为字符串。
		 */
		String str = new String(data, "utf-8");
		System.out.println(str);
		raf.close();
	}

}

基于指针的读写操作

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 使用RAF读写基本类型数据,以及基于指针的读写操作。
 * 
 * @author Jack
 *
 */
public class RafDemo3 {
	public static void main(String[] args) throws IOException{
		RandomAccessFile raf = new RandomAccessFile("raf.dat","rw");
		/**
		 * 获取当前RAF的指针位置,创建RAF时默认从0开始,即:文件第一个字节的位置。
		 */
		long pos = raf.getFilePointer();
		System.out.println("pos:"+pos);
		
		int d = Integer.MAX_VALUE;
		raf.write(d>>>24);
		raf.write(d>>>16);
		raf.write(d>>>8);
		raf.write(d);
		System.out.println("写入完毕!");
		
		/**
		 * RAF提供了方便写出基本类型的方法
		 * 
		 * 连续写4个字节将int值写出
		 * 
		 * 连续写8个字节将long值写出
		 * 
		 */
		raf.writeInt(d);
		raf.writeLong(123L);
		raf.writeDouble(123.123);
		System.out.println("pos:"+raf.getFilePointer());
		/**
		 * void seek (long pos)
		 * 移动指针到指定位置
		 */
		raf.seek(0);
		System.out.println("pos:"+raf.getFilePointer());
		
		int num =raf.readInt();
		System.out.println(num);
		System.out.println("pos:"+raf.getFilePointer());
		
		long l =raf.readLong();
		System.out.println(l);
		System.out.println("pos:"+raf.getFilePointer());
		
		double dou = raf.readDouble();
		System.out.println(dou);
		System.out.println("pos:"+raf.getFilePointer());
		raf.close();
	}
}

练习:用户团建

package raf;

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

/**
 * 用户团建
 * 用户在控制台输入四项信息:用户名,密码,昵称,年龄
 * 前三个为字符串,最后一个为int值
 * 并将该信息写入user.dat文件中保存。
 * @author Jack
 *每条记录占用100字节,其中用户名,密码,昵称占32个字节,年龄是int值固定的4字节。
 *字符串故意留白的好处是便于修改,并且固定长度格式也就固定了,读取方便,但是缺点是浪费一点空间。
 */
public class RegDemo {
	public static void main(String[] args) throws IOException {
		System.out.println("欢迎注册");
		Scanner sc = new Scanner(System.in);

		System.out.println("请输入用户名:");
		String username = 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(username + "," + password + "," + nickname + "," + age);

		RandomAccessFile raf = new RandomAccessFile("user.dat", "rw");
		// 先将指针移动到文件末尾,以便追加新纪录
		raf.seek(raf.length());

		// 写用户名
		byte[] data = username.getBytes("UTF-8");
		// 将数组扩容到32字节
		data = Arrays.copyOf(data, 32);
		raf.write(data);

		// 写密码
		data = password.getBytes("UTF-8");
		// 将数组扩容到32字节
		data = Arrays.copyOf(data, 32);
		raf.write(data);

		// 写昵称
		data = nickname.getBytes("UTF-8");
		// 将数组扩容到32字节
		data = Arrays.copyOf(data, 32);
		raf.write(data);
		
		// 写年龄
		raf.writeInt(age);

		System.out.println("pos:" + raf.getFilePointer());

		System.out.println("注册完毕!");

		raf.close();
		
	}
}

练习:读取团建用户信息

package raf;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 将user.dat文件中的所有用户信息读取出来
 * 
 * @author Jack
 * 
 *
 */
public class ShowAllUserDemo {

	public static void main(String[] args) throws IOException {
		RandomAccessFile raf = new RandomAccessFile("user.dat", "r");

		for (int i = 0; i < raf.length() / 100; i++) {
			// 读取用户名
			byte[] data = new byte[32];
			raf.read(data);
			String username = new String(data, "UTF-8").trim();
			System.out.println(username);

			// 读取密码
			data = new byte[32];
			raf.read(data);
			String password = new String(data, "UTF-8").trim();
			System.out.println(password);

			// 读取昵称
			data = new byte[32];
			raf.read(data);
			String nickname = new String(data, "UTF-8").trim();
			System.out.println(nickname);

			// 读取年龄
			int age = raf.readInt();
			System.out.println(age);

			System.out.println("pos:" + raf.getFilePointer());
		}

	}

}

练习:修改团建用户信息

package raf;

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

/**
 * 修改用户名称 程序启动后,要求用户输入用户名及新昵称。然后修改user.dat文件中对应该用户的昵称。若此用户不存在,则提示查无此人。
 * 
 * @author Jack
 *
 */
public class UpdateDemo {

	public static void main(String[] args) throws IOException {
		RandomAccessFile raf = new RandomAccessFile("user.dat", "rw");

		Scanner sc = new Scanner(System.in);
		System.out.println("请输入用户名:");
		String name = sc.nextLine();
		System.out.println("请输入用户新昵称:");
		String nickname = sc.nextLine();

		boolean flag = false; // 是否有进行修改
		String username = "";
		for (int i = 0; i < raf.length() / 100; i++) {
			raf.seek(i * 100);
			// 读取用户名
			byte[] data = new byte[32];
			raf.read(data);
			username = new String(data, "UTF-8").trim();
			if (name.equals(username)) {
				// 先将指针移动到昵称位置
				raf.seek(i * 100 + 64);
				byte[] data1 = nickname.getBytes("UTF-8");
				Arrays.copyOf(data1, 32);
				raf.write(data1);
				System.out.println("修改完毕!");
				flag = true;
				break;
			}
		}
		if (!flag) {
			System.out.println("查无此人!");
		}
		sc.close();
		raf.close();
	}
}

练习:完成简易记事本工具

package raf;

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

/**
 * 练习:完成简易记事本工具
 * 程序启动后,要求用户在控制台输入文件名,然后对该文件进行写操作,之后用户在控制台输入的每一行字符串都要写入到该文件中(字符集统一用UTF-8)。
 * 当用户单独输入exit时,程序退出。
 * 
 * @author Administrator
 *
 */
public class Note {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入文件名:");
		String name = sc.nextLine();
		System.out.println("请输入内容:");
		RandomAccessFile raf = new RandomAccessFile(name, "rw");
		
		write(name);
		sc.close();
	}
    
	public static void write(String name) throws IOException {
		RandomAccessFile raf = new RandomAccessFile(name, "rw");
		raf.seek(raf.length());
		Scanner sc = new Scanner(System.in);
		String line = sc.nextLine();
		if (!"exit".equals(line)) {
			byte[] data = line.getBytes("UTF-8");
			raf.write(data);
			write(name);
		} else {
			System.out.println("程序终止!");
			sc.close();
			raf.close();
		}
	}

}
package raf;

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

public class Note1 {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入文件名:");
		String name = sc.nextLine();
		RandomAccessFile raf = new RandomAccessFile(name, "rw");
		System.out.println("请输入内容:");
		while (true) {
			String line = sc.nextLine();
			if ("exit".equals(line)) {
				break;
			}
			byte[] data = line.getBytes("UTF-8");
			raf.write(data);
		}
		System.out.println("程序终止!");
		sc.close();
		raf.close();
	}

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值