? ? ? ? 以下介紹合并文件的幾種方式,并通過合并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 blocke.printStackTrace();} return finalFile; }
步驟二:合并文件
方式一:?通過FileOutputStream、與FileInputStream方式
/*** 通過FileOutputStream、與FileInputStream方式* 將多個文件進行合并,并刪除原文件* */public void mergeFiles1() {// TODO Auto-generated method stubif (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 blocke.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 blocke.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();} }