我有一个包含字节,字符和对象的文件,所有这些都需要写入然后才能读取。利用Java的不同IO流来编写和读取这些数据类型的最佳方法是什么?更具体地说,是否有一种正确的方法来添加分隔符并识别这些分隔符,然后触发应该使用哪个流?我相信我需要澄清在同一个文件中使用多个流,这是我以前从未研究过的。彻底的解释将是一个充分的答案。谢谢!
答案 0 :(得分:2)
正如 EJP 已经建议的那样,使用ObjectOutputStream和ObjectInputStream an0d将您的其他元素包装为对象。我正在给出一个答案,所以我可以展示一个例子(在评论中很难做到)EJP - 如果你想把它嵌入你的问题中,请做,我会删除答案。
class MyWrapedData implements serializeable{
private String string1;
private String string2;
private char char1;
// constructors
// getters setters
}
写入文件:
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
out.writeObject(myWrappedDataInstance);
out.flush();
从文件中读取
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
Object obj = in.readObject();
MyWrapedData wraped = null;
if ((obj != null) && (obj instanceof MyWrappedData))
wraped = (MyWrapedData)obj;
// get the specific elements from the wraped object
答案 1 :(得分:1)
重新设计文件。没有明智的方法来实现它目前的设计。例如,对象预先假定一个ObjectOutputStream,它有一个标题 - 这将是什么?你怎么知道在哪里从字节切换到字符?
我可能会将ObjectOutputStream用于整个事物并将所有内容写为对象。然后Serialization为您解决所有这些问题。毕竟,你实际上并不关心文件中的内容,只关心如何读写它。
答案 2 :(得分:0)
您可以更改文件的结构吗?目前尚不清楚,因为您的问题的第一句与能够添加描绘符相矛盾。如果您可以更改文件结构,则可以将不同的数据类型输出到单独的文件中。我认为这是划分数据流的“正确”方式。
如果您按照文件的方式处理文件,那么您将需要编写一个文件结构的接口,实际上这是一个读取操作的购物清单和许多异常处理。一种破解性的编程方式,因为它需要一个十六进制编辑器和大量的反复试验,但它在某些情况下有效。
答案 3 :(得分:0)
为什么不把文件写成XML,可能还有一个很好的简单库,比如XSTream。如果你担心空间,请用gzip压缩包装。
答案 4 :(得分:0)
如果您可以控制文件格式,并且它不是特别大的文件(即<1 GiB),您是否考虑过使用Google的协议缓冲区?
它们生成解析(并序列化)文件/ byte []内容的代码。协议缓冲区对每个值使用标记方法,包括(1)字段编号和(2)类型,因此它们具有良好的属性,例如前向/后向兼容性和可选字段等。它们针对速度和文件大小进行了相当好的优化,为短字节[]仅增加约2个字节的开销,在较大的byte []字段(VarInt编码长度)上编码长度约2-4个额外字节。
这可能有点矫枉过正,但如果你有一堆不同的领域&amp;类型,protobuf真的很有帮助。请参阅:http://code.google.com/p/protobuf/。
另一种选择是Facebook的Thrift,支持更多语言,但最后我检查的可能性较少。
答案 5 :(得分:0)
如果文件的结构未修复,请考虑使用每种类型的包装器。首先,您需要创建包装类的接口......
interface MyWrapper extends Serializable { void accept(MyWrapperVisitor visitor); }
然后创建MyWrapperVisitor接口......
interface MyWrapperVisitor { void visit(MyString wrapper); void visit(MyChar wrapper); void visit(MyLong wrapper); void visit(MyCustomObject wrapper); }
然后你创建你的包装类......
class MyString implements MyWrapper { public final String value; public MyString(String value) { super(); this.value = value; } @Override public void accept(MyWrapperVisitor visitor) { visitor.visit(this); } } . . .
最后你读了你的对象......
final InputStream in = new FileInputStream(myfile); final ObjectInputStream objIn = new ObjectInputStream(in); final MyWrapperVisitor visitor = new MyWrapperVisitor() { @Override public void visit(MyString wrapper) { //your logic here } . . . }; //loop over all your objects here final MyWrapper wrapper = (MyWrapper) objIn.readObject(); wrapper.accept(visitor);