Java文件的拆分与合并(二)

来源:互联网 发布:网络剧 余罪 傅国生 编辑:程序博客网 时间:2024/06/01 10:48
package cn.com;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.RandomAccessFile;//文件的拆分和组合//步骤://1 依据源文件大小和每块的大小计算出块数//2 将每一块写到一个对应的文件public class FileSeparatorAndUnite {long rawFileSize;long blocksNumber;String rawFileName=null;String [] allPaths=null;public static void main(String[] args) {         FileSeparatorAndUnite test=new FileSeparatorAndUnite();         //拆分文件         String [] allPaths=test.separatorFile("F:\\2.jpg", 1024*10);         //组合文件         test.uniteFile(allPaths, "F:\\33.jpg");}/** * @param rawFilePath   待拆分文件的路径 * @param perBlockSize  拆分后每份的大小 * @return              各部分路径的数组集合 */private String[] separatorFile(String rawFilePath,long perBlockSize){File rawFile=new File(rawFilePath);rawFileName=rawFile.getName();rawFileSize=rawFile.length();blocksNumber=getBlocksNumber(rawFileSize,perBlockSize);allPaths=new String[(int)blocksNumber];if (blocksNumber==1) {perBlockSize=rawFileSize;}long perPartSize=0;long perPartBeginPosition=0;String perPartPath=null;for (int i = 1; i <=blocksNumber; i++) {if (i<blocksNumber) {//每一块的大小就为perBlockSizeperPartSize=perBlockSize;} else {//最后一块的大小为总大小-该块的起始位置                perPartSize=rawFileSize-perPartBeginPosition;}//得到每一块的pathif (blocksNumber==1) {perPartPath=rawFilePath+".bat";} else {perPartPath=getPerPartFilePath(rawFilePath, i);}//操作每一块//第一次调用时perPartBeginPosition当然为0writePerPartToFile(rawFilePath, perPartPath, perBlockSize, perPartBeginPosition); //计算每一块的在原文件中的起始位置.perPartBeginPosition=perPartBeginPosition+perPartSize;//保存每一块的路径allPaths[i-1]=perPartPath;}return allPaths;}/** * @param rawFilePath       原文件路径 * @param perPartFilePath   每部分对应的路径 * @param blockSize         每部分的块大小 * @param beginPosition     每部分在原文件中的开始位置  * @return * 在这里  len=len-(int)(writedBytes-blockSize)有些不好理解 * 假设blockSize=2100,每次写入1024,那么两次后还剩余 * 2100-1024*2=52 * 如果再写入1024,那么就会报错,超出了最大范围. * 所以还能写入的=blockSize-已经写入的大小(writedBytes) * 因为在if语句前面已经有了赋值语句writedBytes=writedBytes+len; * 所以需要:len=len-(int)(writedBytes-blockSize) * 其实代入:len=len-(int)(writedBytes+len-blockSize) * 可以得知:len=blockSize-writedBytes */public boolean writePerPartToFile(String rawFilePath,String perPartFilePath,long blockSize,long beginPosition){RandomAccessFile raf=null;FileOutputStream fos=null;byte [] buffer=new byte[8*1024];int len=0;long writedBytes=0;try {raf=new RandomAccessFile(rawFilePath, "r");raf.seek(beginPosition);fos=new FileOutputStream(perPartFilePath);while ((len=raf.read(buffer))!=-1) {if (writedBytes<blockSize) {writedBytes=writedBytes+len;if (writedBytes<=blockSize) {fos.write(buffer, 0, len);} else {                        len=len-(int)(writedBytes-blockSize);                        fos.write(buffer, 0, len);}} }} catch (Exception e) {try {if (fos!=null) {fos.close();}if (raf!=null) {raf.close();}} catch (Exception ex) {}return false;}return true;}/** * @param rawFileSize   原文件大小 * @param perBlockSize  每块的大小 * @return              拆分后块数 */public long getBlocksNumber(long rawFileSize,long perBlockSize){if (rawFileSize<=perBlockSize) {return 1;} else {            if (rawFileSize%perBlockSize==0) {return ((rawFileSize/perBlockSize)+1);} else {                return rawFileSize/perBlockSize;}}}/** * @param rawFilePath   原文件路径 * @param blockNumer    当前块号码 * @return              当前块对应的路径 */public String getPerPartFilePath(String rawFilePath,int blockNumer){String perPartFilePath=rawFilePath+".part"+blockNumer;return perPartFilePath;}/** * @param partsPaths      各部分路径 * @param unitedFilePath  合并后文件路径 */public void uniteFile(String [] partsPaths,String unitedFilePath){try {File perPartFile=null;File unitedFile=new File(unitedFilePath);FileOutputStream fos=new FileOutputStream(unitedFile);FileInputStream fis=null;for (int i = 0; i < partsPaths.length; i++) {perPartFile=new File(partsPaths[i]);fis=new FileInputStream(perPartFile);byte [] buffer=new byte[1024*8];int len=0;while ((len=fis.read(buffer))!=-1) {fos.write(buffer, 0, len);}}fis.close();fos.close();} catch (Exception e) {}}}