JAVA基础篇-文件分片与合成实践

本文提供两种文件分片与合成的方法,分别是普通IO流的方式和使用RandomAccessFile的方式,推荐RandomAccessFile方式,接下来请看代码实现:

package com.study.xxl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**	
* @author  xuxile
*/
public class FileSplitAndMergeUtil {
	
	public static void main(String[] args) throws Exception {
//		splitFile1("D:/mysoft/test.exe");// 大文件分片方法1:普通IO方式
//		mergeFile1("D:/mysoft","D:/mysoft/new.exe");//大文件合成方法1:普通IO方式
		splitFile2("D:/mysoft/test.exe");//大文件分片方法2:RandomAccessFile方式
		mergeFile2("D:/mysoft","D:/mysoft/new.exe");//大文件合成方法2:RandomAccessFile方式
	}
	
	/**
	 * 大文件分片方法1:普通IO方式
	 * @param filePath 文件路径
	 * */
	public static void splitFile1(String filePath){
		InputStream bis=null;//输入流用于读取文件数据
		OutputStream bos=null;//输出流用于输出分片文件至磁盘
		try {
			File file=new File(filePath);
			bis=new BufferedInputStream(new FileInputStream(file));
			long splitSize=5*1024*1024;//单片文件大小,5M
	        long writeByte=0;//已读取的字节数
	        int len=0;
	        byte[] bt=new byte[1024];
			while (-1!=(len=bis.read(bt))) {
				if(writeByte%splitSize==0){
					if(bos!=null){
						bos.flush();
						bos.close();
					}
					bos=new BufferedOutputStream(new FileOutputStream(filePath+"."+(writeByte/splitSize+1)+".part"));
				}
				writeByte+=len;
				bos.write(bt, 0, len);
			}
			System.out.println("文件分片成功!");
		} catch (Exception e) {
			System.out.println("文件分片失败!");
			e.printStackTrace();
		}finally {
			try {
				if(bos!=null){
					bos.flush();
					bos.close();
				}
				if(bis!=null){
					bis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 大文件合成方法1:普通IO方式
	 * @param splitDir 分片目录
	 * @param newFilePath 新文件路径
	 * @throws Exception 
	 * */
	public static void mergeFile1(String splitDir,String newFilePath){
		File dir=new File(splitDir);//目录对象
		File[] fileArr=dir.listFiles(new FilenameFilter() {//分片文件
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith(".part");
			}
		});
		List<File> fileList = Arrays.asList(fileArr);
		Collections.sort(fileList, new Comparator<File>() {//根据文件名称对fileList顺序排序
			@Override
			public int compare(File o1, File o2) {
				int lastIndex11=o1.getName().lastIndexOf(".");
				int lastIndex12=o1.getName().substring(0,lastIndex11).lastIndexOf(".")+1;
				int lastIndex21=o2.getName().lastIndexOf(".");
				int lastIndex22=o2.getName().substring(0,lastIndex21).lastIndexOf(".")+1;
				int num1=Integer.parseInt(o1.getName().substring(lastIndex12,lastIndex11));
				int num2=Integer.parseInt(o2.getName().substring(lastIndex22,lastIndex21));
				return num1-num2;
			}
		});
		OutputStream bos=null;
		InputStream bis=null;
		try {
			bos=new BufferedOutputStream(new FileOutputStream(newFilePath));//定义输出流
			for(File file:fileList){//按顺序合成文件
				bis=new BufferedInputStream(new FileInputStream(file));
				int len=0;
			    byte[] bt=new byte[1024];
				while (-1!=(len=bis.read(bt))) {
					bos.write(bt, 0, len);
				}
				bis.close();
			}
			bos.flush();
			bos.close();
			System.out.println("大文件合成成功!");
		} catch (Exception e) {
			System.out.println("大文件合成失败!");
			e.printStackTrace();
		}finally {
			try {
				if(bis!=null){
					bis.close();
				}
				if(bos!=null){
					bos.flush();
					bos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 大文件分片方法2:RandomAccessFile方式
	 * @param filePath 文件路径
	 * */
	public static void splitFile2(String filePath){
		File file=new File(filePath);
		RandomAccessFile in=null;
		RandomAccessFile out =null;
		long length=file.length();//文件大小
		long splitSize=5*1024*1024;//单片文件大小,5M
		long count=length%splitSize==0?(length/splitSize):(length/splitSize+1);//文件分片数
		byte[] bt=new byte[1024];
		try {
			in=new RandomAccessFile(file, "r");
			for (int i = 1; i <= count; i++) {
	            out = new RandomAccessFile(new File(filePath+"."+i+".part"), "rw");//定义一个可读可写且后缀名为.part的二进制分片文件
	            long begin = (i-1)*splitSize;
	            long end = i* splitSize;
	            int len=0;
	            in.seek(begin);
				while (in.getFilePointer()<end&&-1!=(len=in.read(bt))) {
					out.write(bt, 0, len);
				}
				out.close();
			}
			System.out.println("文件分片成功!");
		} catch (Exception e) {
			System.out.println("文件分片失败!");
			e.printStackTrace();
		}finally {
			try {
				if(out!=null){
					out.close();
				}
				if(in!=null){
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 大文件合成方法2:RandomAccessFile方式
	 * @param splitDir 分片目录
	 * @param newFilePath 新文件路径
	 * @throws Exception 
	 * */
	public static void mergeFile2(String splitDir,String newFilePath){
		File dir=new File(splitDir);//目录对象
		File[] fileArr=dir.listFiles(new FilenameFilter() {//分片文件
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith(".part");
			}
		});
		List<File> fileList = Arrays.asList(fileArr);
		Collections.sort(fileList, new Comparator<File>() {//根据文件名称对fileList顺序排序
			@Override
			public int compare(File o1, File o2) {
				int lastIndex11=o1.getName().lastIndexOf(".");
				int lastIndex12=o1.getName().substring(0,lastIndex11).lastIndexOf(".")+1;
				int lastIndex21=o2.getName().lastIndexOf(".");
				int lastIndex22=o2.getName().substring(0,lastIndex21).lastIndexOf(".")+1;
				int num1=Integer.parseInt(o1.getName().substring(lastIndex12,lastIndex11));
				int num2=Integer.parseInt(o2.getName().substring(lastIndex22,lastIndex21));
				return num1-num2;
			}
		});
		RandomAccessFile in=null;
		RandomAccessFile out =null;
		try {
			out=new RandomAccessFile(newFilePath, "rw");
			for(File file:fileList){//按顺序合成文件
				in=new RandomAccessFile(file, "r");
				int len=0;
			    byte[] bt=new byte[1024];
				while (-1!=(len=in.read(bt))) {
					out.write(bt, 0, len);
				}
				in.close();
			}
			System.out.println("文件合成成功!");
		} catch (Exception e) {
			System.out.println("文件合成失败!");
			e.printStackTrace();
		}finally {
			try {
				if(in!=null){
					in.close();
				}
				if(out!=null){
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值