日期:2014-05-20  浏览次数:20858 次

关于java中文件输入输出流问题
我写了个文件分割的小程序 以下是分割部分的代码

/*文件分割方法
参数file表示要分割的源文件
dir表示分割完成后要保存的路径
size表示要分割的大小*/
private void cutFile(File file,File dir,long size) {
  // TODO Auto-generated method stub
  FileInputStream fis=null; //创建文件输入和输出流
  FileOutputStream fos=null;
  long fileSize=file.length(); //取得源文件大小
  String fileName=file.getName(); //取得原文件名字
  long fileNum=0; //附加在分割好后文件名后面的文件编号
  try {
  fis=new FileInputStream(file);
  fileNum=0;
  if(fileSize<=1024){
  JOptionPane.showMessageDialog(null,"文件不需要分割");
  return;
  }
  int readByte=0;
  byte[]date=new byte[1024]; //缓存数组
  int singleFileSize=0; //分割文件大小临时变量
  File nextFile=null;
  //读取源文件直到文件末尾
  while((readByte=fis.read(date))!=-1){
  if(nextFile==null)
  nextFile=new File(dir,fileName+"."+"cut"+fileNum); //创建分割后的单个文件
  if(fos==null){
  fos=new FileOutputStream(nextFile); //创建分割后单个文件的输出流
  }
   
  /*
  if(singleFile<size){
fos.write(date,0,readByte);
singleFileSize+=readByte;
}
else{
info.append(nextFile.getName()+"\n");
fos.close();
singleFileSize=0;
fileNum++;
nextFile=new File(dir,fileName+"."+"cut"+fileNum);
fos=new FileOutputStream(nextFile);
}

  */
  if(singleFileSize>=size){ //如果分割的文件大小等于或大于指定的分割大小重新创建一个文件
  info.append(nextFile.getName()+"\n"); //在信息拦添加文件名
  fos.close();
  singleFileSize=0;
  fileNum++;
  nextFile=new File(dir,fileName+"."+"cut"+fileNum);
  fos=new FileOutputStream(nextFile);
  }
  fos.write(date,0,readByte);
  singleFileSize+=readByte;
   
  }
   
  if(fos!=null){
   
  fos.close();
  }
  if(fis!=null){
  fis.close();
  }
  info.append(nextFile.getName()+"\n"); 
  } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  }
  }

以上代码不考虑中间那段加粗的注释部分 分割出来的文件是正常的

但如果我把注释部分代码替换掉以下代码 分割出来的文件总数大小比原文件小了30多KB这是为什么按理来说2种if语句完成的功能能应该是一样的

 if(singleFileSize>=size){ //如果分割的文件大小等于或大于指定的分割大小重新创建一个文件
  info.append(nextFile.getName()+"\n"); //在信息拦添加文件名
  fos.close();
  singleFileSize=0;
  fileNum++;
  nextFile=new File(dir,fileName+"."+"cut"+fileNum);
  fos=new FileOutputStream(nextFile);
  }
  fos.write(date,0,readByte);
  singleFileSize+=readByte;



------解决方案--------------------
Java code
当然不一样了
if(singleFile<size){
fos.write(date,0,readByte); //这里的代码是有条件执行的,满足else的时候就不会执行这里
singleFileSize+=readByte;
}
else{
info.append(nextFile.getName()+"\n");
fos.close();
singleFileSize=0;
fileNum++;
nextFile=new File(dir,fileName+"."+"cut"+fileNum);
fos=new FileOutputStream(nextFile);
}

而
if(singleFileSize>=size){ //如果分割的文件大小等于或大于指定的分割大小重新创建一个文件
  info.append(nextFile.getName()+"\n"); //在信息拦添加文件名
  fos.close();
  singleFileSize=0;
  fileNum++;
  nextFile=new File(dir,fileName+"."+"cut"+fileNum);
  fos=new FileOutputStream(nextFile);
  }
  fos.write(date,0,readByte); //这里的代码是无条件执行的,不管满足不满足上面的if,都会执行
  singleFileSize+=readByte;

所以,第一种方法,当满足else时,就不会执fos.write(date,0,readByte); 而丢失信息
而第二种是,即使满足了if,也还是会执行fos.write(date,0,readByte); 不会丢失信息