Java核心技术:随机访问文件
Posted junjie2019
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java核心技术:随机访问文件相关的知识,希望对你有一定的参考价值。
import java.io.*; import java.time.LocalDate; import java.util.Scanner; public class Test { public static void main(String[] args){ // TextFileTest.test(); RandomAccessTest.test(); } } class Employee { private String name; private double salary; private LocalDate hireDay; public static final int NAME_SIZE = 30; public static final int RECORD_SIZE = 50; public Employee(String name, double salary, LocalDate hireDay) { this.name = name; this.salary = salary; this.hireDay = hireDay; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public LocalDate getHireDay() { return hireDay; } public void setHireDay(LocalDate hireDay) { this.hireDay = hireDay; } @Override public String toString() { return "Employee{" + "name=‘" + name + ‘‘‘ + ", salary=" + salary + ", hireDay=" + hireDay + ‘}‘; } } class TextFileTest { public static void test() { Employee[] staff = new Employee[]{ new Employee("A", 10, LocalDate.now()), new Employee("B", 20, LocalDate.now()), new Employee("C", 30, LocalDate.now()) }; try(PrintWriter out = new PrintWriter("employee.dat","UTF-8")) { writeData(staff,out); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } try (Scanner in = new Scanner(new FileInputStream("employee.dat"))) { Employee[] newStaff = readData(in); for (Employee e : newStaff) { System.out.println(e); } } catch (FileNotFoundException e) { e.printStackTrace(); } } private static void writeData(Employee[] employees, PrintWriter out) { out.println(employees.length); for (Employee e : employees) { writeEmployee(out,e); } } private static void writeEmployee(PrintWriter out, Employee employee) { out.println(employee.getName()+"|"+employee.getSalary()+"|"+ employee.getHireDay()); } private static Employee[] readData(Scanner in) { int n = in.nextInt(); in.nextLine(); Employee[] employees = new Employee[n]; for (int i = 0; i < n; i++) { employees[i] = readEmployee(in); } return employees; } private static Employee readEmployee(Scanner in) { String line = in.nextLine(); String[] tokens = line.split("\|"); String name = tokens[0]; double salary = Double.parseDouble(tokens[1]); LocalDate hire = LocalDate.parse(tokens[2]); return new Employee(name, salary, hire); } } /* 写了大半天,突然发现这个实验好像不是太严谨: 1.RandomAccessFile算长度时,应该是根据字节数算出来的 2.写字符串时,我们只是指定了码元数量,我们写的是固定码元数量的字符串 3.这样的化,我们记录的Employee.RECORD_SIZE根本就代表不了一条记录的长度 4.但是我们最后又通过RandomAccessFile的长度和Employee.RECORD_SIZE来计算记录数量 5.我觉得这个实验有问题,以后研究吧 */ class DataIO { //Java核心技术 卷二 第十版 2.3.2节 //写出从字符串开头开始的指定数量的码元,如果码元过少,该方法会用‘0’来补齐字符串 public static void writeFixedString(String s, int size, DataOutput output) throws IOException { for (int i = 0; i < size; i++) { char ch =0; if(i<s.length()) ch = s.charAt(i); output.write(ch); } } //Java核心技术 卷二 第十版 2.3.2节 //从输入流中读入字符,直至读入size个码元,或者直至遇到具有0值的字符串,然后跳出输入字段中剩余的0值。 public static String readFixedString1(int size, DataInput in) throws IOException { StringBuilder sb = new StringBuilder(); for (int i = 0; i < size; i++) { char c; if ((c = in.readChar()) != 0) { sb.append(c); } } return sb.toString(); } //功能和上一个方法是一样的,但是这个效率会高那么一点点 public static String readFixedString2(int size, DataInput in) throws IOException { StringBuilder sb = new StringBuilder(); /* int i; for (i = 0; i < size; i++) { char c; if ((c = in.readChar()) == 0) { break; } sb.append(c); } in.skipBytes(2*(size-i)); //这个地方不是太严谨 */ //用书中代码测试一下 int i =0; boolean more = true; while (more && i < size) { char ch = in.readChar(); i++; if (ch == 0) { more = false; } else { sb.append(ch); } } in.skipBytes(2 * (size - i)); return sb.toString(); } } class RandomAccessTest { public static void test() { Employee[] staff = new Employee[]{ new Employee("A", 10, LocalDate.now()), new Employee("B", 20, LocalDate.now()), new Employee("C", 30, LocalDate.now()) }; //写入 try(DataOutputStream out = new DataOutputStream(new FileOutputStream("employee1.dat"))) { for (Employee e : staff) { writeData(out, e); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //读取 try(RandomAccessFile in = new RandomAccessFile("employee1.dat","r")) { int n = (int) (in.length() / Employee.RECORD_SIZE); Employee[] newStaff = new Employee[n]; for (int i = n - 1; i >= 0; i--) { in.seek(i*Employee.RECORD_SIZE); newStaff[i] = readDate(in); } for (Employee e : newStaff) { System.out.println(e); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void writeData(DataOutput out, Employee employee) throws IOException { DataIO.writeFixedString(employee.getName(), Employee.NAME_SIZE, out); out.writeDouble(employee.getSalary()); LocalDate hireDay = employee.getHireDay(); out.writeInt(hireDay.getYear()); out.writeInt(hireDay.getMonthValue()); out.writeInt(hireDay.getDayOfMonth()); } private static Employee readDate(DataInput input) throws IOException { String name = DataIO.readFixedString2(Employee.NAME_SIZE, input); double salary = input.readDouble(); int y= input.readInt(), m= input.readInt(), d= input.readInt(); return new Employee(name, salary, LocalDate.of(y, m, d)); } }
以上是关于Java核心技术:随机访问文件的主要内容,如果未能解决你的问题,请参考以下文章