Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用不同IO流写入/读取文件的正确方式是什么_Java_File Io_Iostream_Inputstream_Outputstream - Fatal编程技术网

Java 使用不同IO流写入/读取文件的正确方式是什么

Java 使用不同IO流写入/读取文件的正确方式是什么,java,file-io,iostream,inputstream,outputstream,Java,File Io,Iostream,Inputstream,Outputstream,我有一个包含字节、字符和对象的文件,所有这些都需要先写后读。利用Java的不同IO流来编写和读取这些数据类型的最佳方法是什么?更具体地说,是否有合适的方法添加分隔符并识别这些分隔符,然后触发应该使用的流?我相信我需要一些关于在同一个文件中使用多个流的澄清,这是我以前从未研究过的。一个彻底的解释就足够了。谢谢 重新设计文件。按照目前的设计,没有合理的实施方法。例如,该对象假定有一个ObjectOutputStream,它有一个头-它将去哪里?你怎么知道从字节到字符的转换呢 我可能会在整个过程中使用

我有一个包含字节、字符和对象的文件,所有这些都需要先写后读。利用Java的不同IO流来编写和读取这些数据类型的最佳方法是什么?更具体地说,是否有合适的方法添加分隔符并识别这些分隔符,然后触发应该使用的流?我相信我需要一些关于在同一个文件中使用多个流的澄清,这是我以前从未研究过的。一个彻底的解释就足够了。谢谢

重新设计文件。按照目前的设计,没有合理的实施方法。例如,该对象假定有一个ObjectOutputStream,它有一个头-它将去哪里?你怎么知道从字节到字符的转换呢


我可能会在整个过程中使用ObjectOutputStream,并将所有内容都作为对象写入。然后序列化为您解决所有这些问题。毕竟你实际上并不关心文件中有什么,只关心如何读写。

你能改变文件的结构吗?这是不清楚的,因为你问题的第一句话与能够添加描绘者相矛盾。如果可以更改文件结构,则可以将不同的数据类型输出到单独的文件中。我认为这是划定数据流的“适当”方式。


如果您无法按原样处理文件,则需要为文件结构编写一个接口,实际上,该接口是一个读取操作的购物列表和大量异常处理。这是一种骇人的编程方式,因为它需要一个十六进制编辑器和大量的尝试和错误,但在某些情况下可以工作。

为什么不将文件编写为XML,可能使用一个很好的简单库,如XSTream。如果您关心空间,请使用gzip压缩来包装它。

如果您可以控制文件格式,并且它不是一个非常大的文件(即<1 GiB),您是否考虑过使用Google的协议缓冲区

它们生成解析(并序列化)文件/字节[]内容的代码。协议缓冲区对包括(1)字段编号和(2)类型的每个值都使用标记方法,因此它们具有良好的属性,例如与可选字段的向前/向后兼容性等。它们在速度和文件大小方面都进行了相当好的优化,只为短字节[]增加了约2字节的开销,使用~2-4个额外字节对较大字节[]字段的长度进行编码(可变编码长度)

这可能有些过分,但如果您有一堆不同的字段和类型,protobuf确实很有用。请参阅:


另一种选择是Facebook的Thrift,它支持更多的语言,尽管我上次检查时可能在野外使用较少。

正如已经建议的那样,使用ObjectOutputStream和ObjectInputStream并将其他元素包装为对象。我给出一个答案,这样我就可以展示一个例子(很难在评论中这样做)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

这里看到非常明显的例子:和

如果文件的结构不固定,请考虑使用每种类型的包装器。首先,您需要创建包装器类的接口

interface MyWrapper extends Serializable { void accept(MyWrapperVisitor visitor); } 接口MyWrapper扩展了可序列化{ 无效接受(MyWrapperVisitor); } 然后创建MyWrapperVisitor接口

interface MyWrapperVisitor { void visit(MyString wrapper); void visit(MyChar wrapper); void visit(MyLong wrapper); void visit(MyCustomObject wrapper); } 接口MyWrapperVisitor{ 无效访问(MyString包装器); 无效访问(MyChar包装); 无效访问(MyLong); 无效访问(MyCustomObject包装器); } 然后创建包装器类

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); } } . . . 类MyString实现MyWrapper{ 公共最终字符串值; 公共MyString(字符串值){ 超级(); 这个值=值; } @凌驾 公共无效接受(MyWrapperVisitor){ 访客。访问(本); } } . . . 最后你读你的物品

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); final InputStream in=新文件InputStream(myfile); 最终ObjectInputStream objIn=新ObjectInputStream(in); 最终MyWrapperVisitor=新MyWrapperVisitor(){ @凌驾 公共无效访问(MyString包装器){ //你的逻辑在这里 } . . . }; //在这里循环所有对象 final MyWrapper=(MyWrapper)objIn.readObject(); 接受(访客);
你能把整个文件读成一个字节流,然后在里面找到你的分隔符,把部分放到字节数组中,然后把它们读成各自的流吗?这可能会一直持续到需要读取的对象,但是我觉得可能有一种更直接的方法。所以我把文件中的所有内容都作为对象转储。我该如何读回它?@Trevor Arjeski用writeObject()写,用readObject()读,并转换为byte[],char[],你的类等等。我的错误,我确实可以控制文件的结构这是一个很好的例子,说明了如何读写对象,但它没有解决这样一个事实,即我的文件中也有必须与对象区分开来的原语。@Trevor Arjeski-这正是它所显示的-将原语包装在“MyWrapedData”对象中。我只包括字符串和字符,但它也可以是任何其他原语。首先,你将包装它们的对象保存在一个文件中,然后用同样的方法读取对象并提取原语。哦,对不起,我甚至没有看这个对象。现在我明白了!谢谢能不能在wrappedData对象中放置一个对象?@Trevor-当然,就像在类中放置任何其他对象一样。