Java如何将文件进行拆分和合并呢?

书欣 Java经验 发布时间:2023-01-23 21:24:50 阅读数:18070 1
下文笔者讲述使用java代码将文件进行拆分和合并的方法分享,如下所示
实现思路:
    1.将文件转换为字节数组
	2.然后对数组按照指定大小进行分隔
	  采用这种方式,即可实现文件的拆分
	 反向操作,即可实现文件的合并操作
例:文件拆分和合并的示例
 
package com.java265;
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("D:\\test.jpg", 1024*10);
         //组合文件
         test.uniteFile(allPaths, "D:\\test888.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) {
				//每一块的大小就为perBlockSize
				perPartSize=perBlockSize;
			} else {
				//最后一块的大小为总大小-该块的起始位置
                perPartSize=rawFileSize-perPartBeginPosition;
			}
			//得到每一块的path
			if (blocksNumber==1) {
				perPartPath=rawFilePath+".bat";
			} else {
				perPartPath=getPerPartFilePath(rawFilePath, i);
			}
			//操作每一块
			//第一次调用时perPartBeginPosition当然为0
			System.out.println("该Block开始位置:perPartBeginPosition="+perPartBeginPosition);
			writePerPartToFile(rawFilePath, perPartPath, perPartSize, perPartBeginPosition); 
			//计算每一块的在原文件中的起始位置.
			perPartBeginPosition=perPartBeginPosition+perPartSize;
			//保存每一块的路径
			allPaths[i-1]=perPartPath;
			
			System.out.println("该Block大小:perPartSize="+perPartSize);
			
		}
		return allPaths;
		
	}
	
	/**
	 * @param rawFilePath       原文件路径
	 * @param perPartFilePath   每部分对应的路径
	 * @param blockSize         每部分的块大小
	 * @param beginPosition     每部分在原文件中的开始位置 
	 * @return
	 * 
	 * rafForReader.read(buffer, 0, everyTimeReadLen)
	 * 表示:向buffer中读入everyTimeReadLen个字节
	 */
	public boolean writePerPartToFile(String rawFilePath,String perPartFilePath,long blockSize,long beginPosition){
		RandomAccessFile rafForReader=null;
		RandomAccessFile rafForWriter=null;
		boolean isContinueReading=true;
		//每次应该读取的字节数 
		int everyTimeReadLen=0;
		byte [] buffer=new byte[1024*8];
		try {
			rafForReader=new RandomAccessFile(rawFilePath, "r");
			rafForReader.seek(beginPosition);
			File perPartFile=new File(perPartFilePath);
			rafForWriter=new RandomAccessFile(perPartFile, "rw");
			//设置文件大小
			rafForWriter.setLength(blockSize);
			int writerOff=0;
			//设置第一次read()应该读取的字节
			if (blockSize>buffer.length) {
				everyTimeReadLen=buffer.length;
			}else {
				everyTimeReadLen=(int)blockSize;
			}
			while (rafForReader.read(buffer, 0, everyTimeReadLen)!=-1&&isContinueReading){
				  rafForWriter.seek(writerOff);
				  writerOff+=everyTimeReadLen;
				  rafForWriter.write(buffer, 0, everyTimeReadLen);
				  //动态改变下次该读取的字节数
				  if (blockSize-writerOff>buffer.length) {
						everyTimeReadLen=buffer.length;
					}else {
						everyTimeReadLen=(int)blockSize-writerOff;
					}
				  //读取完毕
				  if (everyTimeReadLen==0) {
					isContinueReading=false;
				}
			}
			rafForReader.close();
			rafForWriter.close();
		} catch (Exception e) {
			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);
			} else {
                return (rawFileSize/perBlockSize)+1;
			}
		}
	}
	
	/**
	 * @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) {
		}
	}
}
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202301/16744803505500.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者