在我的作业中
writePosting(FileChannel fc, PostingList posting)
它似乎使用 fc 来写入类 postingList 的内容,其中 PostingList 包含一个整数和一个列表。
但我发现 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();
}
}
}
还有一个额外的方法,readPosted :
@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]]