ObjectOutputStream 追加写入读取错误

摘自http://blog.csdn.net/mitkey/article/details/50274543

问题描述:

用类ObjectOutputStream向文件写读对象时,碰到一个问题:新建一个文件,用输出流ObjectOutputStream向文件连续写几个对象,关闭输出流,然 后读取,这些对象都可以读出;这时在向该文件增加对象,新写的对象就读不出了

问题出现的原因:

ObjectOutputStream建立后第一次写入一个对象时, 会在对象数据前写入一些标志的数据“AC ED  00 05”(用二进制方式查看打开),应该是流相关的信息。当你关闭 ObjectOutputStream 后再重新打开往文件里面写对象时(append方式),就会再一次把“AC ED 00 05”写入文件,而这些信息并不是你写入对象的数据,所以当你用ObjectInputStream来读取对象时,流会将除第一个“AC ED 00 05”以外的数据当作各个对象的数据,造成无法解析,所以读取时有一个java.io.StreamCorruptedException出现。 这个可以通过编辑Info.dat来验证,只要将“AC ED 00 05”删除(第一个“AC ED 00 05”保留)就可以正常读出后来加入的对象。 给出一个比较笨的解决方法: 在以后要添加新的对象到Info.dat时,将里面原有的对象读出放入ArrayList中,清空文件,再将对象集一次写入。

尝试解决办法:

那个“AC ED 00 05”是  ObjectOutputStream.writeSystemHeader()写进去的,你可以继承ObjectOutputStream类,覆盖这个方法。 在你自己的writeSystemHeader()里判断是不是第一次写入一个文件,如果是向一个文件大小不为零的文件追加的话,就调用  super.reset(),如果是第一次写这个文件,不是追加,就调用super.writeSystemHeader()

自定义类MyObjectOutputStream

[java] view plain copy

  1. /**
  2. * 此类继承ObjectOutputStream,重写writeStreamHeader()方法,以实现追加写入时去掉头部信息
  3. */
  4. public static class MyObjectOutputStream extends ObjectOutputStream {
  5. private static File f;
  6. // writeStreamHeader()方法是在ObjectOutputStream的构造方法里调用的
  7. // 由于覆盖后的writeStreamHeader()方法用到了f。如果直接用此构造方法创建
  8. // 一个MyObjectOutputStream对象,那么writeStreamHeader()中的f是空指针
  9. // 因为f还没有初始化。所以这里采用单态模式
  10. private MyObjectOutputStream(OutputStream out, File f) throws IOException, SecurityException {
  11. super(out);
  12. }
  13. // 返回一个MyObjectOutputStream对象,这里保证了new MyObjectOutputStream(out, f)
  14. // 之前f已经指向一个File对象
  15. public static MyObjectOutputStream newInstance(File file, OutputStream out) throws IOException {
  16. f = file;// 本方法最重要的地方:构建文件对象,两个引用指向同一个文件对象
  17. return new MyObjectOutputStream(out, f);
  18. }
  19. @Override
  20. protected void writeStreamHeader() throws IOException {
  21. // 文件不存在或文件为空,此时是第一次写入文件,所以要把头部信息写入。
  22. if (!f.exists() || (f.exists() && f.length() == 0)) {
  23. super.writeStreamHeader();
  24. } else {
  25. // 不需要做任何事情
  26. }
  27. }
  28. }

测试方法:

[java] view plain copy

  1. public static void writeObject() throws Exception {
  2. String filename = "test.txt";
  3. File f = new File(filename);
  4. OutputStream os = new FileOutputStream(f, true);
  5. MyObjectOutputStream moos = MyObjectOutputStream.newInstance(f, os);
  6. moos.writeObject("abc");
  7. moos.writeObject(1);
  8. moos.close();
  9. }

时间: 2024-12-25 18:45:46

ObjectOutputStream 追加写入读取错误的相关文章

Java读取txt文件和覆盖写入txt文件和追加写入txt

package thread; import java.io.*; public class hh { /** * 创建文件 * @param fileName * @return */ public static boolean createFile(File fileName)throws Exception{ try{ if(!fileName.exists()){ fileName.createNewFile(); } }catch(Exception e){ e.printStackT

net快速写入/读取大量数据Postgresql

Postgresql快速写入/读取大量数据 http://www.cnblogs.com/podolski/p/7152144.html 环境及测试 使用.net驱动npgsql连接post数据库.配置:win10 x64, i5-4590, 16G DDR3, SSD 850EVO. postgresql 9.6.3,数据库与数据都安装在SSD上,默认配置,无扩展. CREATE TABLE public.mesh ( x integer NOT NULL, y integer NOT NUL

Java基础知识强化之IO流笔记20:FileOutputStream写出数据实现换行和追加写入

1.  如何实现数据的换行? (1) 1 package com.himi.fileoutputstream; 2 3 import java.io.FileNotFoundException; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 8 /** 9 * 10 * 如何实现数据换行? 11 * 12 */ 13 14 15 public class FileOutputStreamDemo4 { 1

Android中写入读取XML

获取XML文件的基本思路是,通过getResources().getXml()获的XML原始文件,得到XmlResourceParser对象,通过该对象来判断是文档的开头还是结尾,是某个标签的开始还是结尾,并通过一些获取属性的方法来遍历XML文件,从而访问XML文件的内容,下面是一个访问XML文件内容的例子,并将内容更显示在一个TextView上 数据写入xml: ReadXMLTest.java [java] view plaincopy //xml数据生成 private String Wr

C#学习笔记(22)——C#创建文本文件txt并追加写入数据

说明(2017-7-31 16:25:06): 1. 有两种办法,第一种是用FileStream创建txt,用StreamWriter写入数据,期间还要加上判断,是否存在这个txt文件,如果不存在就创建,存在就追加写入.太麻烦了! 2. 第二种是直接File.AppendAllText(string path, string contents);第一个参数是txt路径+文件名,第二个参数是写入内容.这个方法会自己判断文件是否存在,直接一步到位! using System; using Syste

ios cordite 读取错误CoreData could not fulfill a fault for '0x15b4a870

解释在这里 http://stackoverflow.com/questions/14296892/nsobjectinaccessibleexception-reason-coredata-could-not-fulfill-a-fault 这里是中文的详细解释 http://blog.csdn.net/meegomeego/article/details/17654947 关于这个问题,我们涉及到2个函数: /* returns the object for the specified ID

ava如何追加写入txt文件

(一)总述br/>java中,对文件进行追加内容操作的三种方法:import?java.io.BufferedWriter;import?java.io.FileOutputStream;import?java.io.FileWriter;import?java.io.IOException;import?java.io.OutputStreamWriter;import?java.io.PrintWriter;import?java.io.RandomAccessFile;//如果文件存在,则

去除 \ufeff——访问网址或读取文件莫名其妙无法读取错误——raise InvalidSchema("No connection adapters were found for '%s'" % url) requests.exceptions.InvalidSchema: No connection adapters were found for

raise InvalidSchema("No connection adapters were found for '%s'" % url)requests.exceptions.InvalidSchema: No connection adapters were found for 访问的网址明明没有问题,却报以上的错误,还以为requests库出问题了呢. 细心排查一下你会发现网址前面可能会有\ufeff这个字符,这就是UFT-8编码导致的. 把 UTF-8 编码 改成 UTF-

openpyxl库实现对excel文档进行编辑(追加写入)

首先,这个库只支持xlsx格式的excel文件 预期,对”excel_test.xlsx“的A1单元格写入”hello word“ 1.安装”openpyxl“库,pip install openpyxl 2.导入openpyxl库 import openpyxl 3.读取excel文件 xfile = openpyxl.load_workbook(path+'\\excel_test.xlsx') 4.获取需要写入的”Sheet“名称,案例里的sheet名为”Sheet1“ sheet = x