来看一段ObjectOutputStream构造方法的源代码
public ObjectOutputStream(OutputStream out) throws IOException {
verifySubclass();
bout = new BlockDataOutputStream(out);
handles = new HandleTable(10, (float) 3.00);
subs = new ReplaceTable(10, (float) 3.00);
enableOverride = false;
/
* The writeStreamHeader method is provided so subclasses can append or
* prepend their own header to the stream. It writes the magic number and
* version to the stream.
*
* @throws IOException if I/O errors occur while writing to the underlying
* stream
*/
writeStreamHeader();
bout.setBlockDataMode(true);
if (extendedDebugInfo) {
debugInfoStack = new DebugTraceInfoStack();
} else {
debugInfoStack = null;
}
}
意思就是在创建一个ObjectOutputStream的时候,这个ObjectOutputStream流中就已经被写入了一些信息,这些信息会写入到我们的文件中。在第一次写入文件时,这些头部信息时需要的,因为ObjectInputStream读的时候会帮我们过滤掉。但是当我们追加写入一个文件时,这些头部信息也会写入文件中,读取的时候只会把文件第一次出现的头部信息过滤掉,并不会把文件中间的头部信息也过滤掉,这就是问题的根源所在。
解决办法如下:
可以通过继承ObjectOutputStream来覆盖这个方法,如果不是第一次写入文件,这个方法什么也不做。
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/**
* 此类继承ObjectOutputStream,重写writeStreamHeader()方法,以实现追加写入时去掉头部信息
*/
public class MyObjectOutputStream extends ObjectOutputStream {
private static File f;
// writeStreamHeader()方法是在ObjectOutputStream的构造方法里调用的
// 由于覆盖后的writeStreamHeader()方法用到了f。如果直接用此构造方法创建
// 一个MyObjectOutputStream对象,那么writeStreamHeader()中的f是空指针
// 因为f还没有初始化。所以这里采用单态模式
private MyObjectOutputStream(OutputStream out, File f) throws IOException,
SecurityException {
super(out);
}
// 返回一个MyObjectOutputStream对象,这里保证了new MyObjectOutputStream(out, f)
// 之前f已经指向一个File对象
public static MyObjectOutputStream newInstance(File file, OutputStream out)
throws IOException {
f = file;// 本方法最重要的地方:构建文件对象,两个引用指向同一个文件对象
return new MyObjectOutputStream(out, f);
}
@Override
protected void writeStreamHeader() throws IOException {
// 文件不存在或文件为空,此时是第一次写入文件,所以要把头部信息写入。
if (!f.exists() || (f.exists() && f.length() == 0)) {
super.writeStreamHeader();
} else {
// 不需要做任何事情
}
}
}
参考:http://blog.csdn.net/touch_2011/article/details/6853871
分享到:
相关推荐
在Java编程语言中,将多个小文件合并成一个文件是一个常见的需求,特别是在处理大量数据或者进行文件归档时。这个过程通常称为文件拼接或文件合并。以下将详细讲解如何使用Java来实现这一功能。 首先,我们需要理解...
本教程将深入探讨如何利用PB9的功能将数据窗口导出到一个Excel文件的不同工作表中,从而实现更高效的数据管理和分析。 首先,理解数据窗口的基本操作至关重要。数据窗口可以设计为多种样式,如表格、报告或图表,它...
同时,可以将压缩后的文件合并到一个单一的压缩文件中,例如通过创建一个内存流(`MemoryStream`)来临时存储每个文件的压缩结果,然后再写入到最终的GZIP文件。 四、压缩文件夹 压缩整个文件夹需要递归地处理...
可以通过使用CSingleLock或CCriticalSection等同步对象来确保在任何时候只有一个线程能访问文件,防止数据冲突。 此外,调试时,可以借助串口调试助手工具,如RealTerm或PuTTY,实时查看串口通信的数据流,这有助于...
- **合并文件**:一种方法是将所有文件合并成一个大文件,然后提供单一的下载链接。这可以通过读取每个文件的字节流,然后写入新的文件来实现。优点是用户只需点击一次即可下载所有文件,但缺点是如果文件过大,...
接着,使用`FindNextFile()`持续查找下一个文件,直到没有更多的文件。 3. **检查文件类型**:在遍历过程中,对每个文件检查其扩展名是否符合要求。如果匹配,就跳过;如果不匹配,就继续查找下一个文件。 4. **...
在IT行业中,尤其是在数据处理和自动化任务中,有时我们需要将多个Excel文件合并成一个单一的文件,以便于管理和分析大量数据。在这个场景下,使用编程语言如C#可以实现这样的功能。本文将深入探讨如何使用C#在...
本篇文章将详细讲解如何将多个Dataset的数据导出到一个Excel文件的不同Sheet中,以及涉及的相关技术。 首先,我们来理解核心概念: 1. **Dataset**: 在.NET框架中,Dataset是一个轻量级的对象,可以用来存储和操作...
本文将详细探讨如何使用DEV GridControl的GridView组件将数据导出到Excel,并且支持将多个GridView导出到同一个Excel文件的不同Sheet中。这是一项实用的技术,能够帮助开发者提高工作效率,便于用户对大量数据进行...
2. **设计下载任务**:每个下载任务是一个Runnable对象,内部包含文件URL、本地保存路径以及断点续传所需的信息(如已下载的字节数)。 3. **检查本地进度**:在开始下载前,检查本地是否存在已下载的部分,如果有...
对于同时读取多个文件,你可以创建多个libxl的工作簿对象,然后逐个打开文件,读取数据,关闭文件。这种方式速度快,但功能可能相对有限,不支持所有Excel特性。 4. **并发处理多个文件**: 在VC++中,可以利用多...
它可以允许用户从本地计算机选择一个或多个文件,并将这些文件上传到服务器。在多文件上传中,我们需要确保控件的`Multiple`属性设置为`true`,以便支持同时选择多个文件。 方法一:使用HTML5的FormData对象 在现代...
标题 "PB数据窗口导出PDF并且合并到一个PDF文件中" 涉及的主要知识点是使用PowerBuilder(PB)这个编程工具,对数据窗口对象进行操作,并将结果以PDF格式导出,最后实现多个PDF文件的合并。在这个过程中,我们不仅...
- **任务拆分**:将大任务分解为多个小任务,每个任务由一个线程处理,充分利用多核处理器资源。 - **线程优先级**:合理设置线程优先级可以调整线程执行顺序,但不保证优先级高的线程一定先执行。 7. **异常处理...
在QT框架下,利用TCP协议实现一个多线程的文件互传系统是一项常见的任务,它涉及到网络编程、多线程处理以及文件操作等多个方面。本文将深入探讨这些关键知识点。 首先,TCP(Transmission Control Protocol)是一...
内存映射文件并不是真的将整个文件加载到物理内存中,而是创建一个映射对象,这个对象代表了文件在虚拟内存中的视图。当需要访问文件内容时,操作系统会自动调度磁盘I/O,将所需的数据放入内存中。这样,通过指针...
DXF文件由多个部分组成,如头部信息、图层定义、实体等。Netdxf库提供了丰富的类来表示这些元素,如`DxfHeader`、`DxfLayer`和`DxfEntity`。开发者可以根据需要访问和修改这些元素,实现对DXF文件的精确控制。 5. ...
封装了一个ajax多文件上传,功能就是选择多个文件,ajax...调用方式很简单,写一个json对象做为参数配置,设置要上传url以及事件处理函数,new一个AjaxUploadX对象,调用selectFiles方法选择文件,调用uplaod方法上传。
3. **日志缓冲区**:使用队列作为日志缓冲区,线程安全地将日志项添加到队列,然后由单独的后台线程负责从队列中取出并写入文件,避免了多个线程同时写入的冲突。 4. **日志文件切分**:当单个日志文件大小达到预设...
3. 将大数据文件切分到多个小文件中 4. 使用LinkedList存储文件流对象和BufferedWriter对象 5. 对每个小文件的数据进行排序 6. 对多个小文件的数据进行比较和整合 7. 使用System.currentTimeMillis()方法记录操作的...