DataInputStream类和RandomAccessFile类的使用方法

// DataInputStream类实现了DataInput接口,要想从文件中读入二进制数据,
// 你需要将DataInputStream与某个字节源相结合,例如FileInputStream
// 与此同时,要想写出二进制数据,可以使用实现了DataOutput接口的DataOutputStream类
// RandomAccessFile类同时实现了DataInput和DataOutput接口。
// 以下程序将三条记录写到一个数据文件中,然后以逆序将它们从文件中读回。
// 为了高效地执行,这里需要使用随机访问,因为我们需要首先读入第三条记录
// 让我们来计算每条记录的大小:我们将使用40个字符来 表示姓名字符串,因此每条记录包含100个字节:
// 40字符 = 80字节,用于姓名
// 1 double = 8字节,用于薪水
// 3 int = 12字节,用于日期
package com.example.io;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class RandomFileTest {

    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 {
            // 保存所有雇员记录到文件当中
            DataOutputStream out = new DataOutputStream(new FileOutputStream("employee.dat"));
            for (Employee e : staff) {
                e.writeData(out);
            }
            out.close();

            // 读取所有记录到新数组中
            RandomAccessFile in = new RandomAccessFile("employee.dat", "r");
            // 计算数组的尺寸
            int n = (int) (in.length() / Employee.RECORD_SIZE);
            Employee[] newStaff = new Employee[n];

            //反序读入雇员记录
            for (int i = n - 1, j = 0; i >= 0; i--) {
                newStaff[j] = new Employee();
                in.seek(i * Employee.RECORD_SIZE);
                newStaff[j].readData(in);
                j++;
            }
            in.close();

            // 打印新读入数组记录内容
            for (Employee e : newStaff) {
                System.out.println(e);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

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(DataOutput out) throws IOException {
        DataIO.writeFixedString(name, NAME_SIZE, out);
        out.writeDouble(salary);

        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(hireDay);
        out.writeInt(calendar.get(Calendar.YEAR));
        out.writeInt(calendar.get(Calendar.MONTH) + 1);
        out.writeInt(calendar.get(Calendar.DAY_OF_MONTH));
    }

    public void readData(DataInput in) throws IOException {
        name = DataIO.readFixedString(NAME_SIZE, in);
        salary = in.readDouble();
        int y = in.readInt();
        int m = in.readInt();
        int d = in.readInt();
        GregorianCalendar calendar = new GregorianCalendar(y, m - 1, d);
        hireDay = calendar.getTime();
    }

    public static final int NAME_SIZE = 40;
    public static final int RECORD_SIZE = 2 * NAME_SIZE + 8 + 4 + 4 + 4;
    private String name;
    private double salary;
    private Date hireDay;
}

class DataIO {

    public static String readFixedString(int size, DataInput in) throws IOException {
        StringBuilder b = new StringBuilder(size);
        int i = 0;
        boolean more = true;
        while (more && i < size) {
            char ch = in.readChar();
            i++;
            if (ch == 0) {
                more = false;
            } else {
                b.append(ch);
            }
        }
        in.skipBytes(2 * (size - i));
        return b.toString();
    }

    public static void writeFixedString(String s, int size, DataOutput out) throws IOException {
        for (int i = 0; i < size; i++) {
            char ch = 0;
            if (i < s.length()) {
                ch = s.charAt(i);
            }
            out.writeChar(ch);
        }
    }
}

 

posted @ 2016-02-24 09:51  齐心  Views(948)  Comments(0Edit  收藏  举报