题
我正在尝试将行写入线位置n的文件中。
即使不存在n行。在这种情况下,文件必须用空线生长才能达到n。基本上是类似的 writer.writeLine(n, mycontent)
. 。 MyContent是来自 ObjectOutputStream
. 。文件的每一行都包含一个序列化对象。线数是索引。
如何写入特定行? - 不使用Fileutil或任何非标准API组件。
这个答案 几乎总结了我想要的东西 - 但是写作似乎与众不同。
编辑: 由于评论,我澄清了我的问题
解决方案
线路的概念对您很重要吗?否则,您可能可以在文件中序列化地图,并使用它以特定索引来编写或读取对象(在这种情况下,索引将是地图的关键)。
这是一个例子。
public static void main(String[] args) throws Exception {
ObjectOutputStream tocStream = new ObjectOutputStream(new FileOutputStream("myfile.toc"));
Map<Integer,Object> tableOfContent = new HashMap<Integer, Object>();
String myString = "dataOne";
Date myDate = new Date();
tableOfContent.put(0,myDate);
tableOfContent.put(1,myString);
tocStream.writeObject(tableOfContent);
tocStream.flush();
tocStream.close();
ObjectInputStream tocInputStream = new ObjectInputStream(new FileInputStream("myfile.toc"));
Map<Integer,Object> restoredTableOfContent = (Map<Integer, Object>) tocInputStream.readObject();
Object restoredMyString = restoredTableOfContent.get(1);
System.out.println(restoredMyString);
tocInputStream.close();
}
其他提示
这是行不通的,因为每个序列化对象可能包含一个或几个newline字符作为其二进制表示的一部分。因此,如果您在第3行中编写一个新对象,则很可能会在第一个对象的中间写入对象。测试它:
public class OOSTest {
public static void main(String[] args) throws IOException {
String s = "Hello\nWorld";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(s);
oos.flush();
oos.close();
System.out.println(new String(bos.toByteArray()));
}
}
恕我直言,您有三个选择:
- 选择一个将与二进制数据一起使用的协议(例如:对于每个对象,将其长度(字节)写为整数(4个字节),然后使用对象本身的字节来写;
- 例如,使用base64将序列化字节编码为字符串,并在对象之间使用不属于编码的一部分的对象。
- 使用ObjectOutputStream序列化对象数组。编写一个新的条目将包括对数组的挑选,确保其具有正确的尺寸或将其复制到适当大小的新数组,将对象插入其位置,并在整个数组中得到依赖。
- 通过文件循环读取当前值。
- 将每个值写入新的临时文件。
- 如果旧文件在您的行号之前结束,请继续写出空白行。
- 然后,一旦到达行号,您要更新即可写出新数据。
- 如果旧文件还有更多行,请继续写作。
- 删除旧文件。重命名临时文件。
不隶属于 StackOverflow