今天,碰到一个问题,是关于同时写文件的。背景:
是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?
是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?
好像java写入文件,并不会加上线程锁 也就是说两个线程会同时往文件中写入数据,两个线程的数据会交错再一起,你可以用一个大的文本去试一下,两个线程分别读取不同的文件,然后把数据写入同一个文件中,那文本信息会胡乱交错。
文件写入未加文件锁的原因,在于需要支持多线程写入文件的需要来提高文件写入速度(如多线程下载)。
JDK上是这么写的:可以理解下这句话:文件是否可用或能否可以被创建取决于基础平台。
java.io
类 FileOutputStream
java.lang.Object
java.io.OutputStream
java.io.FileOutputStream
所有已实现的接口:
Closeable, Flushable --------------------------------------------------------------------------------public class FileOutputStreamextends OutputStream文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。