gpt4 book ai didi

java - 如何使用文件 channel 作为参数来写入对象

转载 作者:太空宇宙 更新时间:2023-11-04 14:58:20 25 4
gpt4 key购买 nike

在我的作业中

writePosting(FileChannel fc, PostingList posting)

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

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

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

最佳答案

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

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

}

还有一个额外的方法,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]]

关于java - 如何使用文件 channel 作为参数来写入对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22929248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com