目录
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();
}
}