Google Prettify

2015-05-13

物件的具現─如何將物件存成檔案

Java裡有一種物件叫java.io.Serializable,是可以讓物件在Serialize後在不同的儲存體中傳遞。中文譯做序列化。 今天講講怎麼麼將物件存到硬碟這個儲存體…

假設我有一個物件是這樣:他是一個Serializable的物件。 裡面有一個Collection(datas),可以用來存放Serializable的物件。

public class FileDatas implements Serializable {
    private static final long serialVersionUID = 8048736089512288707L;
    public Collection<Serializable> datas;
    public FileDatas() {
        datas = new HashSet<Serializable>();
    }
    public Collection<Serializable> getDatas() {
        return datas;
    }
}

與另外一個Serializable物件Book

public class Book implements Serializable {
    private static final long serialVersionUID = -4088035671812463272L;
    private String isbn;
    private String author;
    private String name;
    public Book() {
    }
    // Other gets and setters.
    @Override
    public String toString() {
        return "Book [name=" + name + "]";
    }
}

於是我要將Book這個物件存為實體檔案與取得的方式,大概是這樣:

package taichitech.common.db;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.util.Collection;

import org.apache.commons.lang3.SerializationUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileDatasTest {
    Logger logger = LoggerFactory.getLogger(getClass());

    @Test
    public void testSetDatas() {
        try (FileOutputStream fout = new FileOutputStream(filePath);) {
            FileDatas fd = new FileDatas();
            Collection<Serializable> datas = fd.getDatas();
            datas.add(newExampleBook("994-443-989", "Tom Edsion", "How to Generate Java Class?"));
            datas.add(newExampleBook("907-43-169", "Willion Smith", "Eclipse Pro, 2Ed"));
            datas.add(newExampleBook("659-771-01", "Water 13", "如何銷售你自己"));
            logger.debug("Books {}", datas);
            SerializationUtils.serialize(fd, fout);
        } catch (Exception e) {
            logger.error("Fial", e);
        }
    }

    private Book newExampleBook(String isbn, String author, String name) {
        Book b = new Book();
        b.setAuthor(author);
        b.setIsbn(isbn);
        b.setName(name);
        return b;
    }

    private final String filePath = ".filedatas.ser";

    @Test
    public void testGetDatas() {
        try (FileInputStream fin = new FileInputStream(filePath);) {
            FileDatas fd = SerializationUtils.deserialize(fin);
            logger.debug("Books {}", fd.getDatas());
        } catch (Exception e) {
            logger.error("Fial", e);
        }
    }
}

testGetDatas示範了如何將物件存成檔案,而testGetDatas示範如何將檔案再轉回物件。

這裡我主要是使用Apache commons-lang3的SerializationUtils這個物件。 其實deserialize()serialize()裡面就是將Object 轉成ObjectInputStreamObjectOutputStream

延申閱讀:

你可以參考如何轉Serializable物件轉成byte[]

毫無疑問的,打算要存成檔案的物件,都必需要是Serialiazble,所以Collection裡的物件,或是相關property的型別,都必需要是Serializable。

2個UT測試的執行結果如下:

10:38:11.569 [main] DEBUG t.c.db.FileDatasTest[24]-Books [Book [name=Eclipse Pro, 2Ed], Book [name=How to Generate Java Class?], Book [name=如何銷售你自己]]

11:31:45.541 [main] DEBUG t.c.db.FileDatasTest[45]-Books [Book [name=How to Generate Java Class?], Book [name=如何銷售你自己], Book [name=Eclipse Pro, 2Ed]]

儲存的檔案,用文字篇輯器打開會是這個樣子:

這個檔案存了3個Book 物件與一個FileDatas物件

同場加印

我在unit test中產生Book物件的方式就是Factory Method的應用。

延申閱讀:

沒有留言 :

您或許對這些有興趣

Related Posts with Thumbnails

最後

謝謝您的閱讀,希望您可以有豐富的收獲。