摘自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. }

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

  1. ObjectOutputStream 追加写入读取错误 - 自己的实现方案

    本篇博客灵感来自http://blog.csdn.net/chenssy/article/details/13170015 问题描述.问题出现的原因.尝试解决办法,请参见鄙人上一编博客. 上一编文章解 ...

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

    //创建文件 public static void createFile(File filename) { try { if(!filename.exists()) { filename.create ...

  3. python3读取、写入、追加写入excel文件

    由于excel版本不同,python处理的时候选择的库页不同. 一.操作对应版本表格需要用到的库 1.操作xls格式的表格文件,需要用到的库如下: 读取:xlrd 写入:xlwt 修改(追加写入):x ...

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

    Postgresql快速写入/读取大量数据 http://www.cnblogs.com/podolski/p/7152144.html 环境及测试 使用.net驱动npgsql连接post数据库.配 ...

  5. 测开之路七十九:python 文件处理和对象的写入读取

    """处理文件:open(文件名, 模式,编码) 'r' 打开阅读(默认)'w' 打开写入,首先截断文件'x' 打开独占创建,如果文件已经存在则失败'a' 打开写入,追加 ...

  6. JS+Selenium+excel追加写入,使用python成功爬取京东任何商品~

    之前一直是requests库做爬虫,这次尝试下使用selenium做爬虫,效率不高,但是却没有限制,文章是分别结合大牛的selenium爬虫以及excel追加写入操作而成,还有待优化,打算爬取更多信息 ...

  7. 安装vs2013以后,链接数据库总是报内存损坏,无法写入的错误

    安装vs2013以后,链接数据库总是报内存损坏,无法写入的错误 这个错误几个月以前解决过一次,但是到又碰到的时候,竟然完全忘记当时怎么解决的了, 看来上了年纪记忆真是越来越不行了... 解决方案很简单 ...

  8. DataContext 数据在F5刷新频繁,会出现数据读取错误

    DataContext 数据在F5刷新频繁,会出现数据读取错误 DataContext是 Linq to sql数据模型的底层数据库对象所有LInq数据表对象都是由它派生的, 只要建立一个数据库操作, ...

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

    1.  如何实现数据的换行? (1) package com.himi.fileoutputstream; import java.io.FileNotFoundException; import j ...

随机推荐

  1. 关于padding

    例子 1 padding:10px 5px 15px 20px; 上内边距是 10px 右内边距是 5px 下内边距是 15px 左内边距是 20px 例子 2 padding:10px 5px 15 ...

  2. Ubuntu 配置Tomcat环境

    1.下载Tomcat http://tomcat.apache.org/,下载Tomcat 8(由于目前最新eclipse不支持tomcat 9) 将下载的apache-tomcat-8.0.35.t ...

  3. (转)mysql分表的3种方法

    原文:http://blog.51yip.com/mysql/949.html 一,先说一下为什么要分表 当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿 ...

  4. java BingInteger生成2进制String循环移位时长度自动缩减

    最近在做文本处理,使用MD5 生成一段文字的MD5哈希长度为32位也即128个0-1序列. 由于需要对这个MD5值进行循环移位,显然普通的  int 是不行的,所以使用 BigInteger.但是在使 ...

  5. js获取某个标签中的信息

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  6. [core java学习笔记][第十一章异常断言日志调试]

    第11章 异常,断言,日志,调试 处理错误 捕获异常 使用异常机制的技巧 使用断言 日志 测试技巧 GUI程序排错技巧 使用调试器 11.1 处理错误 11.1.1异常分类 都继承自Throwable ...

  7. JS中for循环里面的闭包问题的原因及解决办法

    我们先看一个正常的for循环,普通函数里面有一个for循环,for循环结束后最终返回结果数组 function box(){ var arr = []; for(var i=0;i<5;i++) ...

  8. XMLHttpRequest发送请求

    *open(method,url,async) *send(string)//在使用get请求的时候,是没有主体的,所有的信息都会拼在url当中,所以使用send的时候括号里的string可以为空!如 ...

  9. jQuery 双击事件(dblclick)时,不触发单击事件(click)

    我这是转载的文字 原文地址:http://www.cnblogs.com/wyblog/archive/2011/12/15/2289219.html 万恶的双击事件啊!! 在jQuery的事件绑定中 ...

  10. 提示框的优化之自定义Toast组件之(一)Toast组件的布局实现

    开发步骤:  在res下layout下创建一个Toast的布局资源文件toast_customer.xml  在最外层布局组件中为该布局添加android:id属性  //toast_custo ...