PrintWriter 和 Scanner 类的组合使用
// 示例程序:将一个Employee记录数组存储成一个文本文件,其中每个记录都保存在单独的一行中, // 而实例的域彼此之间使用分隔符分离开。 // 众所周知: // 以二进制格式写出数据,需要使用DataOutputStream // 以文本格式写出数据,需要使用PrintWriter // 你可能认为存在着与DataOutputStream类似的类允许我们以文本格式读入数据,与此最接近的类是Scanner。 // 但在Java SE 5.0之前,处理文本输入的唯一方式就是通过BufferedReader类,它拥有一个readLine方法, // 使得我们可以读入一行文本。你需要将带缓冲区的读入器与输入源组合起来: // BufferedReader in = new BufferedReader(new FileReader("employee.txt")); // readLine方法在没有输入时返回null。然而,一个典型的输入循环类似于这样: // String line; // while((line = in.readLine())!= null) { // do something with line // } // 然而,BufferedReader没有任何用于读入数字的方法,建议使用Scanner来读入文本输入。 package com.example.io; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Scanner; public class TextFileTest { public static void main(String[] args) { Employee[] staff = new Employee[3]; staff[0] = new Employee("Carl Cracker", 75000, 1987, 12, 15); staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1); staff[2] = new Employee("Tony Tester", 40000, 1990, 3, 15); try { PrintWriter out = new PrintWriter("employee.dat"); writeData(staff, out); out.close(); Scanner in = new Scanner(new FileReader("employee.dat")); Employee[] newStaff = readData(in); in.close(); for (Employee e : newStaff) { System.out.println(e); } } catch (IOException e) { e.printStackTrace(); } } private static void writeData(Employee[] employees, PrintWriter out) throws IOException { out.println(employees.length); for (Employee e : employees) { e.writeData(out); } } 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] = new Employee(); employees[i].readData(in); } return employees; } } class Employee { public Employee() { } public Employee(String n, double s, int year, int month, int day) { name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); hireDay = calendar.getTime(); } public String getName() { return name; } public double getSalary() { return salary; } public Date getHireDay() { return hireDay; } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; } @Override public String toString() { return "Employee{" + "name=" + name + ", salary=" + salary + ", hireDay=" + hireDay + '}'; } public void writeData(PrintWriter out) { GregorianCalendar calendar = new GregorianCalendar(); calendar.setTime(hireDay); out.println(name + "|" + salary + "|" + calendar.get(Calendar.YEAR) + "|" + (calendar.get(Calendar.MONTH) + 1) + "|" + calendar.get(Calendar.DAY_OF_MONTH)); } public void readData(Scanner in) { String line = in.nextLine(); String[] tokens = line.split("\\|");//竖线在正则表达式中具有特殊的含义,因此需要用\字符来转义,而这个\又需要用另一个\来转义 name = tokens[0]; salary = Double.parseDouble(tokens[1]); int y = Integer.parseInt(tokens[2]); int m = Integer.parseInt(tokens[3]); int d = Integer.parseInt(tokens[4]); GregorianCalendar calendar = new GregorianCalendar(y, m - 1, d); hireDay = calendar.getTime(); } private String name; private double salary; private Date hireDay; }