[英]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.