文件IO(二)

来源:互联网 发布:potplayer mac 编辑:程序博客网 时间:2024/06/06 03:10

在文件IO中,经常需要写出和读入整个对象。Java提供了在二进制文件中对对象的输出和输入的处理和操作。而对象序列化Serializable,是专门用来提供在二进制文件IO中,对对象的写出和读入技术。序列化的目的是为了在二进制文件执行对对象文件的IO中,保证对象写出和读入的一致性persistence。对输出对象序列化的结果是在输出文件中不仅记录有关对象类型及其状态信息,而且记录封装在对象中的数据及其类型。在读入对象的操作中,则按照对象序列化的信息,进行反序列化deserilazable处理,重新在内存中还原对象。

    序列化的对象必须是实现了Serializable接口的实例。这个接口包括在java.io包中,虽然Serializable接口不提供任何方法需要完善,但提出如下规定:
    序列化对象输出操作必须通过调用private void writeObject(ObjectOutputStream out)方法实现。这个方法将抛出IOException异常,代码中必须提供处理这个异常的机制;
    反序列化对象输入的操作必须通过调用private void readObject(ObjectInputStream in)方法实现。这个方法将抛出IOException和ClassNotFoundException异常,代码中必须提供处理这两个异常的机制。
    其中ObjectOutputStream以及ObjectInputStream为java.io包中提供的用来处理对象序列化IO的API类。

下面是一个对象序列化IO的例子

复制代码
import java.io.EOFException;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.util.Scanner;public class ObjectOutput {    /**     * @param args     * @throws IOException      * @throws FileNotFoundException      */    public static void main(String[] args) throws FileNotFoundException, IOException {        // TODO Auto-generated method stub        String fileName = "D:"+File.separator+"object.bat";        Scanner scanner = new Scanner(System.in);        String choice = "";        System.out.println("read or write or quit? (r/w/q)");        while (!choice.equalsIgnoreCase("q")) {            if (choice.equalsIgnoreCase("r")) {                ObjectFileInput input = new ObjectFileInput();                input.createInputFile(fileName);                input.showData();                input.closeInputFile();                System.out.println("read or write or quit? (r/w/q)");            } else if(choice.equalsIgnoreCase("w")) {                ObjectFileOutput output = new ObjectFileOutput();                output.createOutputFile(fileName);                output.createData(scanner);                output.closeFileOutput();                System.out.println("read or write or quit? (r/w/q)");            }            choice = scanner.next();        }            }} /** * @author xhj * 实现了serializable接口的产品类,生成我们进行对象IO的对象 */class IOProduct implements Serializable {    private int ID;    private String title;    private double price;    private int amount;    public IOProduct() {        // TODO Auto-generated constructor stub    }    public IOProduct(int ID, String title, double price, int amount) {        this.ID = ID;        this.title = title;        this.price = price;        this.amount = amount;    }    public int getID() {        return ID;    }    public String getTitle() {        return title;    }    public double getPrice() {        return price;    }    public int getAmount() {        return amount;    }}/** * @author xhj * 利用获得数据实例化产品类IOProduct,并调用ObjectOut的方法序列化输出对象 */class ObjectFileOutput {    ObjectOut objectOut;    Scanner scanner;    public void createOutputFile(String fileName) {        objectOut = new ObjectOut(fileName);    }    public void createData(Scanner scanner) {        IOProduct product;        int ID;        String title;        double price;        int amount;        String choice = "y";        while (choice.equalsIgnoreCase("y")) {            try {                System.out.print("Enter the IOProduct ID: ");                ID = scanner.nextInt();                // This method returns the rest of the current line, excluding                // any                // line separator at the end. The position is set to the                // beginning                // of the next line.                scanner.nextLine();                System.out.print("Enter the IOProduct title: ");                title = scanner.nextLine();                System.out.print("Enter the IOProduct price: ");                price = scanner.nextDouble();                scanner.nextLine();                System.out.print("Enter the IOProduct amount: ");                amount = scanner.nextInt();                product = new IOProduct(ID, title, price, amount);                objectOut.outObject(product);//将对象写入文件,即序列化            } catch (Exception e) {//如果输入有误                // TODO: handle exception                scanner.nextLine();//清除输入                System.out.println("invalid input, try again!");                continue;           //开始新循环            }                        System.out.print("Continue? (y/n): ");            choice = scanner.next();            System.out.println();        }    }    public void closeFileOutput() {        objectOut.closeFile();    }}/** * @author xhj * 利用ObjectIn的方法读入对象,转化为IOProduct对象并输出对象信息 */class ObjectFileInput {    ObjectIn objectIn;    Object object;    IOProduct product;    public void createInputFile(String fileName) throws FileNotFoundException, IOException {        objectIn = new ObjectIn(fileName);    }    public void showData() {        while (objectIn.hasMore()) {            object = objectIn.inObject();//读取对象,即反序列化操作            if (object instanceof IOProduct) {                product = (IOProduct)object;                System.out.println("Product ID: "+product.getID());                System.out.println("Product title: "+product.getTitle());                System.out.println("Product price: "+product.getPrice());                System.out.println("Product amount: "+product.getAmount());            } else {                break;            }        }    }    public void closeInputFile() throws IOException {        objectIn.closeFile();    }}/** * @author xhj * 定义了序列化输出的操作,利用ObjectOutputStream的writeObject和close方法 */class ObjectOut {    ObjectOutputStream out;    ObjectOut(String name) {        try {            out = new ObjectOutputStream(new FileOutputStream(name));        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public void outObject(Object obj) {        try {            //用ObjectOutputStream的writeObject方法写出            out.writeObject(obj);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public void closeFile() {        try {            out.close();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}/** * @author xhj * 定义了序列化输入的操作,利用ObjectInputStream的readObject和close方法 */class ObjectIn {    ObjectInputStream in;    boolean status = true;    public ObjectIn(String name) throws FileNotFoundException, IOException {        in = new ObjectInputStream(new FileInputStream(name));    }    public Object inObject() {        Object obj = new Object();        try {            //用ObjectInputStream的readObject方法读入            obj = in.readObject();        } catch (EOFException e) {            // TODO: handle exception            System.out.println("End of the file.");            status = false;            return null;        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (ClassNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return obj;    }    public boolean hasMore() {        return status;    }    public void closeFile() throws IOException {        in.close();    }}
复制代码
原创粉丝点击