首页 > 代码库 > Android开发之合并文件的几种方式

Android开发之合并文件的几种方式

        下面介绍合并文件的几种方式,并通过合并amr文件来举例介绍合并文件的具体流程。amr格式的文件头是6字节,所以在进行文件合并的时候要减去除第一个文件以外的其他文件的文件头。

注意:不同文件的文件头是不一样的,所以在合并的时候根据不同文件相应的减去合并文件的文件头。

步骤一:获取要合并的文件及创建合并后保存的文件

/**用于存放要合并的文件的集合**/
List<File>tempFiles=new ArrayList<File>();
/**合并之后的文件**/
File finalFile;
	/**
	 * 创建用于合并之后的文件
	 * @param isTempFile 是否为临时文件
	 * @return soundFile File
	 * */
	private File getFile(boolean isTempFile) {
		// TODO Auto-generated method stub		
		finalFile=null;
		if (!Environment.getExternalStorageState().
				equals(Environment.MEDIA_MOUNTED)) {
			Log.w("Waring", "检测到你的手机没有插入SD卡,请插入SD后再试!");
		}		
		//获取系统的24小时制时间作为文件名(HH为24小时制,hh为12小时制)
		SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
				"yyyy-MM-dd-HH-mm-ss",Locale.getDefault());		
		String fileName=simpleDateFormat.format(new Date())+".amr";	
		if (isTempFile) {//如果是临时文件
			fileName="temp"+fileName;
		}
		try {
			File parentFile= new File(Environment.getExternalStorageDirectory()
					.getCanonicalFile()+"/"+"Recorder");
			if (!parentFile.exists()||parentFile==null) {//如果目录不存在
				parentFile.mkdirs();//创建parentFile目录
			}
			finalFile=new File(parentFile, fileName);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}			
		return finalFile;	
	}

步骤二:合并文件

方式一: 通过FileOutputStream、与FileInputStream方式

	/**
	 * 通过FileOutputStream、与FileInputStream方式
	 * 将多个文件进行合并,并删除原文件
	 * */
	public void mergeFiles1() {
		// TODO Auto-generated method stub
		if (tempFiles.isEmpty()) return;//如果还没录制则,不进行合并
		File realFile=getFile(false);
		try {
			FileOutputStream fos=new FileOutputStream(realFile);		
			for (int i = 0; i < tempFiles.size(); i++) {//遍历tempFiles集合,合并所有临时文件				
				FileInputStream fis=new FileInputStream(tempFiles.get(i));
				byte[] tmpBytes = new byte[fis.available()];
				int length = tmpBytes.length;//文件长度
				//头文件
				if(i==0){
					while(fis.read(tmpBytes)!=-1){
						fos.write(tmpBytes,0,length);
					}
				}					
				//之后的文件,去掉头文件就可以了.amr格式的文件的头信息为 6字节
				else{
					while(fis.read(tmpBytes)!=-1){						
						fos.write(tmpBytes,6,length-6);
					}
				}				
				fos.flush();
				fis.close();		
			}
			fos.close();//所有的文件合并结束,关闭输出流
			Log.i("info", "此次录音文件:"+realFile.getName()+" 已保存到:"+
					realFile.getAbsolutePath()+"目录下");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//删除合并过的临时文件
		for (File file:tempFiles) {
			if (file.exists()) {
				file.delete();
			}
		}
	}

方式二: 通过FileChannel方式

	/**
	 * 通过FileChannel方式
	 * */
	public void mergeFiles2() {
		File realFile=getFile(false);
		FileChannel mFileChannel;
		try {
			FileOutputStream fos=new FileOutputStream(realFile);			
			mFileChannel=fos.getChannel();		
		    FileChannel inFileChannel;
		    for(File file:tempFiles){             
		        inFileChannel=new FileInputStream(file).getChannel();
		        //下面应该根据不同文件减去相应的文件头(这里没有剪去文件头,实际应用中应当减去)
		        inFileChannel.transferTo(0, inFileChannel.size(), mFileChannel);	             
		        inFileChannel.close();
		    }       
		    fos.close();
		    mFileChannel.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

方式三:通过RandomAccessFile方式

	/**
	 * 通过RandomAccessFile方式
	 * */
	public void mergeFiles3() {
		try{				
		    File realFile=getFile(false);
		    FileOutputStream fos = new FileOutputStream(realFile);
		    RandomAccessFile ra = null;
		    for (int i = 0; i < tempFiles.size(); i++) {		    	
		    	ra = new RandomAccessFile(tempFiles.get(i), "r");
			    if (i != 0) {
			    	ra.seek(6);//跳过amr文件的文件头
			    }
			    byte[] buffer = new byte[1024 * 8];
			    int len = 0;
			    while ((len = ra.read(buffer)) != -1) {
			    	fos.write(buffer, 0, len);
			    }
		   }
		   ra.close();
		   fos.close();
		  } catch (Exception e) {
			  e.printStackTrace();
		  }		
	}