FileOutputStream flush操作时有时无效的解决办法

来源:互联网 发布:spss数据分析报告范文 编辑:程序博客网 时间:2024/06/02 23:32

关于flush()方法,api中有如下描述

刷新此输出流并强制写出所有缓冲的输出字节。flush 的常规协定是:如果此输出流的实现已经缓冲了以前写入的任何字节,则调用此方法指示应将这些字节立即写入它们预期的目标。

如果此流的预期目标是由基础操作系统提供的一个抽象(如一个文件),则刷新此流只能保证将以前写入到流的字节传递给操作系统进行写入,但不保证能将这些字节实际写入到物理设备(如磁盘驱动器)。  


FileDescriptor.sync()方法有如下描述


强制所有系统缓冲区与基础设备同步。该方法在此 FileDescriptor 的所有修改数据和属性都写入相关设备后返回。特别是,如果此 FileDescriptor 引用物理存储介质,比如文件系统中的文件,则一直要等到将与此 FileDesecriptor 有关的缓冲区的所有内存中修改副本写入物理介质中,sync 方法才会返回。 sync 方法由要求物理存储(比例文件)处于某种已知状态下的代码使用。例如,提供简单事务处理设施的类可以使用 sync 来确保某个文件所有由给定事务造成的更改都记录在存储介质上。 sync 只影响此 FileDescriptor 的缓冲区下游。如果正通过应用程序(例如,通过一个 BufferedOutputStream 对象)实现内存缓冲,那么必须在数据受 sync 影响之前将这些缓冲区刷新,并转到 FileDescriptor 中(例如,通过调用 OutputStream.flush)。

该问题的可能出现原因是,当flush之后,可能并没有被写入到目的地,这时调用sync方法强制同步一下,应该可以解决这个问题。

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;class SyncDemo{public static void main(String[] args){if (args.length == 0){System.err.println("java Main <inputfile> <outputfile>");System.exit(-1);}try{FileInputStream in = new FileInputStream(args[0]);FileOutputStream out = new FileOutputStream(args[1]);// 如果该文件描述符有效if (in.getFD().valid()){byte[] buf = new byte[512];int count;while ((count = in.read(buf)) > 0){out.write(buf, 0, count);}}in.close();// 刷新数据并将数据转交给操作系统out.flush();// 强制系统缓冲区与基础设备同步// 将系统缓冲区数据写入到文件out.getFD().sync();out.close();}catch (IOException e){e.printStackTrace();}}}