简体   繁体   English

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

[英]how to use filechannel as argument to write object

In my homework 在我的作业中

writePosting(FileChannel fc, PostingList posting)

It seems to use fc to write contents of a class postingList, where PostingList contain an integer and a List. 似乎使用fc编写了一个类postingList的内容,其中PostingList包含一个整数和一个List。

But I find fc could only write bytes?....I do not even understand, why we put FileChannel as a parameter rather than a inputStream? 但是我发现fc只能写字节吗?...我什至都不明白,为什么我们将FileChannel作为参数而不是inputStream?

Could it write directly an integter or string? 它可以直接写一个整数或字符串吗? thanks! 谢谢!

You can accomplish that using serialization. 您可以使用序列化来完成。

Class PostingList : 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: 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();
            }
        }

    }

And an extra method, readPosting : 还有一个额外的方法,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;
    }

And a little test in the main method: 并在主要方法中进行一些测试:

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();
        }

    }

Basically, this is reading/writing serialized objects into a file, but with FileChannel instead of the classic way. 基本上,这是将序列化对象读/写到文件中,但是使用FileChannel而不是经典方式。

EDIT: 编辑:

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM