今天,碰到一个问题,是关于同时写文件的。背景:
是web系统,两个用户同时上传文件,上传的文件保存的时候,Server的算法产生了同一个文件名。
导致文件被覆盖了。但是文件名产生方法里是有时间戳的,不过是到秒。也就是说两个人在同一秒之内
上传的文件。而且文件很大(600M左右)一秒肯定写不完。到现在还很正常,我感觉这两个人其中一个会出错,但是都很正常的执行完了,被保存的文件是较大的那个。
估计是执行的时间长吧。
但是未什么没出IO异常呢?代码:
String fullPath = XXX(生成文件名)
File output= new File(fullPath);
String outputPath = null;
OutputStream os = null;
try{
   os = new FileOutputStream(output);
  IOUtils.copy(inputFile.getInputStream(),os);
  // inputFile.getInputStream()是上传的文件流
  outputPath = output.getCanonicalPath();
} catch(IOException e){
    try{ if(os != null) {
           os.close();}
    } catch(IOException ex){
      throw new XXException(ex);
  }
throw new XXException(e);
}问题我已经回避了(时间戳到毫秒就行了),我只想知道为什么不出IOException?

解决方案 »

  1.   

    文件名用:秒 + 原子化的递增序列 就可以了。文件写入是没法并发操作的,A 在写的时候,B 只能等着,等 A 写完了 B 再去写。
      

  2.   

    这个我知道,所以程序没有产生异常才奇怪啊!而且我debug这模拟了一下,就是两个进程一起写的。而且还不出错。奇怪了。
      

  3.   


    好像java写入文件,并不会加上线程锁 也就是说两个线程会同时往文件中写入数据,两个线程的数据会交错再一起,你可以用一个大的文本去试一下,两个线程分别读取不同的文件,然后把数据写入同一个文件中,那文本信息会胡乱交错。
    文件写入未加文件锁的原因,在于需要支持多线程写入文件的需要来提高文件写入速度(如多线程下载)。
      

  4.   


    JDK上是这么写的:可以理解下这句话:文件是否可用或能否可以被创建取决于基础平台。
    java.io 
    类 FileOutputStream
    java.lang.Object
      java.io.OutputStream
          java.io.FileOutputStream
    所有已实现的接口: 
    Closeable, Flushable --------------------------------------------------------------------------------public class FileOutputStreamextends OutputStream文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。