如何使用filechannel作为写对象的参数

时间:2014-04-08 06:30:08

标签: java file

在我的作业中

writePosting(FileChannel fc, PostingList posting)

似乎使用fc来编写类postsList的内容,其中PostingList包含一个整数和一个List。

但我发现fc只能写字节?....我甚至不明白,为什么我们把FileChannel作为参数而不是inputStream?

可以直接写一个整数或字符串吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您可以使用序列化来实现这一目标。

班级PostingList

public class PostingList<T extends Serializable> implements Serializable{

private static final long serialVersionUID = 6893022784519772456L;
private Integer number;
private List<T> list;

public PostingList(Integer number, List<T> list) {
    super();
    this.number = number;
    this.list = list;
}

@Override
public String toString() {
    return "PostingList [number=" + number + ", list=" + list + "]";
}
}

writePosting:

public static void writePosting(FileChannel fc, PostingList<Integer> posting)
            throws IOException {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(posting);
            oos.flush();
            byte[] postingBytes = baos.toByteArray();

            System.out.println("Bytes read: " + postingBytes.length);

            ByteBuffer buffer = ByteBuffer.allocate(postingBytes.length);
            // prepare buffer to fill with data.
            buffer.clear();
            // write the bytes
            buffer.put(postingBytes);
            // prepare for writing
            buffer.flip();
            fc.write(buffer);
        } finally {
            if (oos != null) {
                oos.close();
            }
            if (baos != null) {
                baos.close();
            }
        }

    }

还有一个额外的方法,readPosting:

@SuppressWarnings({ "rawtypes", "unchecked" })
    private static PostingList<Integer> readPosting(FileChannel fc)
            throws IOException, ClassNotFoundException {

        // Better to set this to a higher number
        byte[] barray = new byte[32];

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ByteBuffer buffer = ByteBuffer.allocate(32);
        int bytesRead = 0;

        while ((bytesRead = fc.read(buffer)) != -1) {

            buffer.flip();
            buffer.get(barray, 0, bytesRead);
            bos.write(barray, 0, bytesRead);
            buffer.clear();

            // for testing
            System.out.println(bytesRead);
        }
        // We write the bytes recovered to an object
        byte[] bytes = bos.toByteArray();
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        Object obj = null;
        try {
            bis = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bis);
            obj = ois.readObject();
        } finally {
            if (bis != null) {
                bis.close();
            }
            if (ois != null) {
                ois.close();
            }
        }
        return (PostingList) obj;
    }

主要方法中的一点测试:

public static void main(String[] args) {

        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 5; i++) {
            list.add(i);
        }
        PostingList<Integer> pl = new PostingList<Integer>(100, list);
        File f = new File("out.dat");

        RandomAccessFile raf = null;
        FileChannel fc = null;
        try {
            raf = new RandomAccessFile(f, "rw");
            fc = raf.getChannel();
            writePosting(fc, pl);
            fc.close();
            raf.close();

            raf = new RandomAccessFile(f, "r");
            fc = raf.getChannel();
            System.out.println(readPosting(fc));
            fc.close();
            raf.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            if (fc!=null) {
                try {
                    fc.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (raf!=null) {
                try {
                    raf.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

基本上,这是将序列化对象读/写到文件中,但使用FileChannel而不是经典方式。

编辑:

输出:

Bytes read: 301
32
32
32
32
32
32
32
32
32
13
PostingList [number=100, list=[0, 1, 2, 3, 4]]