package raf;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* java.io.RandomAccessFile
* 随机访问文件
* 是专门用来读写文件数据的类,其基于 指针 对文件进行随机访问,读写操作灵活。
*
* @author YanLy
* @date 2021/5/26 15:41
*/
public class Test1_RAF {
public static void main(String[] args) throws IOException {
/*
RandomAccessFile 常用的构造器
RandomAccessFile(String path,String mode)
RandomAccessFile(File file,String mode)
第一个参数是要操作的文件,可以直接给路径,也可以指定一个File对象
第二个参数是操作模式:r - 只读模式,rw - 读写模式。
如果指定的文件不存在,会直接创建出来。
*/
RandomAccessFile raf = new RandomAccessFile("./raf.txt","rw");
/*
void write(int d): 向文件中写入一个字节,写入的是int值对应的2进制的"低八位"
0b00000000_00000000_00000000_00000001;
"低八位"
*/
raf.write('中');
raf.write(1);
raf.write(2);
System.out.println("文件写出完毕!");
// 关闭流 关了以后就不能用了 如果不关闭 会占用系统资源
raf.close();
// Scanner 也需要关闭流
// Scanner名.close()
//
// 关闭之后可以打开,可以重新new创建
}
}
package raf;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* @author YanLy
* @date 2021/5/26 16:19
*/
public class Test2_RAF2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("./raf.txt", "r");
/*
int read(): 读取一个字节并以int形式返回(读取的数据在int值对应的二进制的第八位上)
如果返回的int值为 -1 则表示文件末尾
*/
// read() 只能读取一个字节
// 00000000_00000000_00000000_00000001
int b = raf.read();
System.out.println(b);
// 00000000_00000000_00000000_00000010
b = raf.read();
System.out.println(b);
b = raf.read();
System.out.println(b);
b = raf.read();
System.out.println(b);
b = raf.read();
System.out.println(b);
b = raf.read();
System.out.println(b);
b = raf.read();
System.out.println(b);
b = raf.read();
System.out.println(b);
b = raf.read();
System.out.println(b);
raf.close();
}
}
package raf;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 读写基本类型数据,以及RAF基于指针的读写操作
*
* @author YanLy
* @date 2021/5/26 16:47
*/
public class Test3 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
long pos = raf.getFilePointer(); // 获取指针的位置
System.out.println("pos: " + pos); // 0,默认从头开始 pos: 0
/*
max = 0b01111111_11111111_11111111_11111111; 2147483647
max >> 24
max1 = 0b00000000_00000000_00000000_01111111; 127
max >> 16
max2 = 0b00000000_00000000_01111111_11111111;
max >> 8
max3 = 0b00000000_01111111_11111111_11111111;
*/
int max = Integer.MAX_VALUE;
raf.write(max>>24); // 127
raf.write(max>>16); // 255
raf.write(max>>8); // 255
raf.write(max); // 255
System.out.println("pos: " + raf.getFilePointer()); // pos: 4
raf.writeInt(max); // 连续写4个字节将int值写入文件,等同上面四句
System.out.println("pos: " + raf.getFilePointer()); // pos: 8
raf.writeLong(12345L);// 连续写8个字节将long值写入文件
System.out.println("pos: " + raf.getFilePointer()); // pos: 16
raf.writeDouble(3.1415926);// 连续写8个字节将double值写入文件
System.out.println("pos: " + raf.getFilePointer()); // pos: 24
// void seek() : 将指针移动到指定位置
raf.seek(0); // 移动到文件最开始位置
// 读取 int
int a = raf.readInt();
System.out.println(a); // 2147483647
System.out.println("pos: " + raf.getFilePointer()); // pos: 4
// 读取 long
// 指针跳转 读取 long
raf.seek(8);
long b = raf.readLong();
System.out.println(b); // 12345
System.out.println("pos: " + raf.getFilePointer()); // pos: 16
// 读取 double
raf.seek(16);
double c = raf.readDouble();
System.out.println(c); // 3.1415926
System.out.println("pos: " + raf.getFilePointer()); // pos: 24
// 修改 long 的值为 56789
raf.seek(8);
raf.writeLong(56789L);
System.out.println("pos: " + raf.getFilePointer()); // 16
raf.seek(8);
long e = raf.readLong();
System.out.println(e); // 56789
System.out.println("pos: " + raf.getFilePointer()); // 16
raf.close();
}
}
package raf;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 文件的复制
*
* @author YanLy
* @date 2021/5/28 11:44
*/
public class Test4_CopyDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("./API.CHM", "r");
RandomAccessFile desc = new RandomAccessFile("./API_copy.CHM", "rw");
long start = System.currentTimeMillis(); // 开始毫秒
int d;// 用于记录每次读取到的字节
// (d = raf.read()) 写到外面不会参加循环了
while ((d = raf.read()) != -1) {
desc.write(d);
}
long end = System.currentTimeMillis(); // 结束毫秒
System.out.println("复制完成,共耗时:" + (end - start) + "ms"); // 401216
raf.close();
}
}
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 通过提高每次实际读写的数据量,减少实际读写的次数可以提高读写效率
* 单字节读写属于随机读写模式,一组字节读写属于块读写。
* 对于机械硬盘来说,随机读写的效率非常差,块读写效率还是不错的。
*
* @author YanLy
* @date 2021/5/28 14:05
*/
public class Test5_CopyDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("./API.CHM","r");
RandomAccessFile desc = new RandomAccessFile("./API_copy.CHM","rw");
/*
int read(byte[] data) :
一次性从文件中读取给定的字节组总长度的字节量,并存入到该数组中,
返回值为实际读取到的字节量,如果返回-1则表示文件末尾。
void write(byte[] data) : 一次性将给定的字节数组中的所有字节写入文件。
void write(byte[] data,int offset,int len) :
将给定的字节数组从下标为offset处的连续len个字节一次性写出
当读取的数据小于数组的大小时,会有多余的默认值存在。
所以在写出数据时,需要把多余的内容舍弃掉,
write(byte[]data.int offset,int len)
第一个参数是要写出的数组,
第二个参数是指定从哪儿开始写出,
第三个参数是写出的长度。
8位 是 8bit
00000000 1byte(1字节)
1024 byte = 1 kb
1024 kb = 1 mb
1024 mb = 1 gb
1024 gb = 1
*/
// 数组的长度要求只能填写int
byte [] data = new byte[1024*10]; // 10kb
int len; // 记录每次实际读取到的字节数
long start = System.currentTimeMillis(); // 开始毫秒
while((len = src.read(data)) != -1){
// 从原文件中实际读取到多少字节,就写多少字节
/**
* 为什么要把data写在参数里:
* 答:从输入流中读取一定数量的字节,src.read(data),并将其存储在缓冲区数组 len 中。
*/
desc.write(data,0,len);
}
long end = System.currentTimeMillis(); // 结束毫秒
System.out.println("复制完成,共耗时:" + (end - start) + "ms"); // 401216
src.close(); // 关闭流
}
}
package raf;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 向文件中写入字符串
*
* @author YanLy
* @date 2021/5/28 15:27
*/
public class Test6_WriteStringDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("raf.txt","rw");
/*
GBK : 国际编码 英文占1个字节 中文占2个字节
UTF-8 : 万国码 英文占1个字节 中文占 3个字节
*/
String line = "就让秋风带走我的思念,带走我的泪~";
/*
byte[] getBytes(): 将字符串按照指定字符集转换为字节数组
getBytes() 方法是 String 类中的方法
byte[] getBytes(String charsetName):
将字符串按照指定字符集转换为字节数组,参数为编码集的名字
如果编码集名字拼写有误 会抛出异常:
UnsupportedEncodingException
*/
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 YanLy
* @date 2021/5/28 15:24
*/
public class Test7_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类里的一个构造方法 参数为数组,还可以指定编码集
// 将字节数组所有内容按照UTF-8字符集还原为字符串
String str = new String(data,"UTF-8");
System.out.println(str);
raf.close();
}
}
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;
/**
* 实现简易记事本
* 程序启动后要求用户输入一个文件名,然后对该文件进行写操作,
* 之后用户在控制台输入的每一行字符串都写入到该文件中(不考虑换行问题),
* 当用户单独输入 "exit" 时程序退出
*
* @author YanLy
* @date 2021/5/28 15:56
*/
public class Test8_Note {
public static void main(String[] args) throws IOException {
// 让用户输入文件名和文件内容
Scanner scanner = new Scanner(System.in);
System.out.println("请输入文件名:");
String scan = scanner.nextLine();
System.out.println("请输入文件内容:");
// 向文件中写入字符串
RandomAccessFile raf = new RandomAccessFile(scan+".txt","rw");
while(true) {
String info = scanner.next();
// 把判断放前面再写
// 已知内容的放在前面
if("exit".equals(info)){
break;
}
byte [] data1 = info.getBytes("UTF-8");
raf.write(data1);
System.out.println("保存成功!") ;
}
raf.close();
System.out.println("再见,欢迎下次使用!");
}
}
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Scanner;
/**
* 完成用户注册功能:
* 程序启动后,要求用户顺序输入:用户名,密码,昵称,年龄
* 然后将该用户信息 写入文件user.txt
* 设计格式:每条记录固定占用100字节
* 其中用户名、密码、昵称各占32字节
* 年龄固定4字节
* (对于字符串而言,故意留白的好处就是后期可以在添加字符,
* 不会影响其他数据,而且长度固定,有利于指针的移动操作)
*
* @author YanLy
* @date 2021/5/28 17:34
*/
public class Test9_RegDemo {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入名字:");
String name = scanner.next();
System.out.println("请输入密码:");
String password= scanner.next();
System.out.println("请输入昵称:");
String nickname = scanner.next();
System.out.println("请输入年纪:");
int age = scanner.nextInt();
RandomAccessFile raf = new RandomAccessFile("user.txt","rw");
// 把指针调到文件的长度
raf.seek(raf.length());
// 设置姓名
byte [] data = name.getBytes("UTF-8");
data = Arrays.copyOf(data,32);
raf.write(data);
// 设置密码
data = password.getBytes("UTF-8");
data = Arrays.copyOf(data,32);
raf.write(data);
// 设置昵称
data = nickname.getBytes("UTF-8");
data = Arrays.copyOf(data,32);
raf.write(data);
// 设置年龄
raf.writeInt(age);
System.out.println("写入完毕!");
// 关闭流
raf.close();
}
}
package raf;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
/**
* @author YanLy
* @date 2021/5/29 9:27
*/
public class Test10_RegDemo1 {
public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("user.txt","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();
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);
}
raf.close();
}
}