有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用filechannel作为参数来编写对象

在我的家庭作业中

writePosting(FileChannel fc, PostingList posting)

它似乎使用fc来编写类postingList的内容,其中postingList包含一个整数和一个列表

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

它能直接写整数或字符串吗?谢谢


共 (1) 个答案

  1. # 1 楼答案

    您可以使用序列化来实现这一点

    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 + "]";
    }
    }
    

    书面记录:

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

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

    @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而不是classic方式

    编辑:

    输出:

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