前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >文件分割与合并

文件分割与合并

作者头像
shimeath
发布2020-07-30 17:08:43
1.4K0
发布2020-07-30 17:08:43
举报

通过RandomAccessFile对象进行文件分割与合并

SplitFile类的初始化

类包含的变量

代码语言:javascript
复制
	private String filePath;		//源文件路径
	private String fileName;		//源文件名
	private long blockSize;			//块大小
	private long length;			//总长度
	private String destPath;		//目标路径
	private List<String> blockPath;	//块路径
	private int size;				//块数量

构建函数

代码语言:javascript
复制
	//均需调用无参构造器,初始化块路径ArrayList
	public SplitFile() {
		blockPath = new ArrayList<String>();
	}
	//未指定块大小时默认1024
	public SplitFile(String filePath, String destPath) {
		this(filePath, 1024, destPath);
	}
	//接收三个参数:源文件路径,块大小,目标文件路径
	public SplitFile(String filePath, long blockSize, String destPath) {
		this();
		this.filePath = filePath;
		this.blockSize = blockSize;
		this.destPath = destPath;
		init();
	}
构造器中调用的初始化函数
代码语言:javascript
复制
	//进行基本判断,确定文件存在且不是目录并确定块数以此确定每一块文件名
	private void init() {
		File src = null;
		//判断文件是否存在
		if (null == filePath || !(((src = new File(filePath)).exists()))) {
			return;
		}
		//判断是否为目录
		if (src.isDirectory())
			return;
		//为对象的文件名字段赋值
		this.fileName = src.getName();
		//确定总长度
		length = src.length();
		//计算块数:总长度/块大小向上取整
		size = (int) (Math.ceil(length * 1.0 / blockSize));
		//确定每一块文件名及路径
		initPathName();
	}

	private void initPathName() {
		for (int i = 0; i < size; i++) {
			this.blockPath.add(destPath + "\\" + i);
		}
	}

分割文件

代码语言:javascript
复制
	public void split() {
		//开始位置
		long beginPos = 0;
		//实际块大小
		long actualBlockSize = blockSize;
		for (int i = 0; i < size; i++) {
			//如果是最后一块
			if (i == size - 1) {
				//总长度-已经分割完毕的长度
				actualBlockSize = length - beginPos;
			}
			//分割文件实现细节
			splitDetail(i, beginPos, actualBlockSize);
			//将开始位置移动到下一个位置
			beginPos += actualBlockSize;
		}
	}

分割文件实现细节

代码语言:javascript
复制
	private void splitDetail(int i, long beginPos, long actualBlockSize) {
		//对源文件和目标文件进行关联
		File src = new File(filePath);
		File dest = new File(this.blockPath.get(i));
		//建立随机访问流和缓冲输出流
		RandomAccessFile raf = null;
		BufferedOutputStream bos = null;
		try {
			//设定模式为只读
			raf = new RandomAccessFile(src, "r");
			bos = new BufferedOutputStream(new FileOutputStream(dest));
			//设定偏移,确定下次读取的位置
			raf.seek(beginPos);
			//中间变量,与其他流读取一致
			byte[] flush = new byte[1024];
			int len = 0;
			while (-1 != (len = raf.read(flush))) {
				//判断是否为到达文件尾
				if (actualBlockSize - len >= 0) {
					bos.write(flush, 0, len);
					actualBlockSize -= len;
				} else {
					//到达文件尾部,写入实际大小数据
					bos.write(flush, 0, (int) actualBlockSize);
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bos.close();
				raf.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

合并文件

采用迭代器以及合并流进行文件合并

代码语言:javascript
复制
	public void merge(aString destPath) {
		File dest = new File(destPath);
		BufferedOutputStream bos = null;
		SequenceInputStream sis = null;
		//创立新迭代器
		Vector<InputStream> vi = new Vector<InputStream>();
		try {
			//将每个文件名存储到迭代器中
			for (int i = 0; i < blockPath.size(); i++) {
				vi.add(new BufferedInputStream(new FileInputStream(new File(blockPath.get(i)))));
			}
			bos = new BufferedOutputStream(new FileOutputStream(dest));
			sis = new SequenceInputStream(vi.elements());

			byte[] flush = new byte[1024];
			int len = 0;
			//读取合并流中的数据并写入到新文件中
			while (-1 != (len = sis.read(flush))) {
				bos.write(flush, 0, len);
			}
			bos.flush();
			sis.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

采用普通方法合并文件

代码语言:javascript
复制
	public void merge1(String destPath) {
		File dest = new File(destPath);
		BufferedOutputStream bos = null;
		try {
			bos = new BufferedOutputStream(new FileOutputStream(dest));
			BufferedInputStream bis = null;
			for (int i = 0; i < blockPath.size(); i++) {
				bis = new BufferedInputStream(new FileInputStream(new File(blockPath.get(i))));

				byte[] flush = new byte[1024];
				int len = 0;
				while (-1 != (len = bis.read(flush))) {
					bos.write(flush, 0, len);
				}
				bos.flush();
				bis.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

主函数

代码语言:javascript
复制
	public static void main(String[] args) {
		SplitFile sp = new SplitFile("D:\\aa\\b\\新建 Microsoft Excel 工作表.xlsx", 50, "d:/aa");
		System.out.println(sp.length);
		sp.split();
		sp.merge("d:/aa/新建 Microsoft Excel 工作表.xlsx");
	}

完整代码

代码语言:javascript
复制
package cn.hxh.io.other;

import java.util.*;
import java.io.*;
import java.lang.Math;

public class SplitFile {
	private String filePath;		//源文件路径
	private String fileName;		//源文件名
	private long blockSize;			//块大小
	private long length;			//总长度
	private String destPath;		//目标路径
	private List<String> blockPath;	//块路径
	private int size;				//块数量

	public SplitFile() {
		blockPath = new ArrayList<String>();
	}

	public SplitFile(String filePath, String destPath) {
		this(filePath, 1024, destPath);
	}

	public SplitFile(String filePath, long blockSize, String destPath) {
		this();
		this.filePath = filePath;
		this.blockSize = blockSize;
		this.destPath = destPath;
		init();
	}

	private void init() {
		File src = null;
		if (null == filePath || !(((src = new File(filePath)).exists()))) {
			return;
		}
		if (src.isDirectory())
			return;
		this.fileName = src.getName();
		length = src.length();
		size = (int) (Math.ceil(length * 1.0 / blockSize));
		initPathName();

	}

	private void initPathName() {
		for (int i = 0; i < size; i++) {
			this.blockPath.add(destPath + "\\" + i);
		}
	}

	public void split() {
		long beginPos = 0;
		long actualBlockSize = blockSize;
		for (int i = 0; i < size; i++) {
			if (i == size - 1) {
				actualBlockSize = length - beginPos;
			}
			splitDetail(i, beginPos, actualBlockSize);
			beginPos += actualBlockSize;
		}
	}

	private void splitDetail(int i, long beginPos, long actualBlockSize) {
		File src = new File(filePath);
		File dest = new File(this.blockPath.get(i));
		RandomAccessFile raf = null;
		BufferedOutputStream bos = null;
		try {
			raf = new RandomAccessFile(src, "r");
			bos = new BufferedOutputStream(new FileOutputStream(dest));

			raf.seek(beginPos);

			byte[] flush = new byte[1024];
			int len = 0;
			while (-1 != (len = raf.read(flush))) {
				if (actualBlockSize - len >= 0) {
					bos.write(flush, 0, len);
					actualBlockSize -= len;
				} else {
					bos.write(flush, 0, (int) actualBlockSize);
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bos.close();
				raf.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	public void merge(String destPath) {
		File dest = new File(destPath);
		BufferedOutputStream bos = null;
		SequenceInputStream sis = null;
		Vector<InputStream> vi = new Vector<InputStream>();
		try {
			for (int i = 0; i < blockPath.size(); i++) {
				vi.add(new BufferedInputStream(new FileInputStream(new File(blockPath.get(i)))));
			}
			bos = new BufferedOutputStream(new FileOutputStream(dest));
			sis = new SequenceInputStream(vi.elements());

			byte[] flush = new byte[1024];
			int len = 0;
			while (-1 != (len = sis.read(flush))) {
				bos.write(flush, 0, len);
			}
			bos.flush();
			sis.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void merge1(String destPath) {
		File dest = new File(destPath);
		BufferedOutputStream bos = null;
		try {
			bos = new BufferedOutputStream(new FileOutputStream(dest));
			BufferedInputStream bis = null;
			for (int i = 0; i < blockPath.size(); i++) {
				bis = new BufferedInputStream(new FileInputStream(new File(blockPath.get(i))));

				byte[] flush = new byte[1024];
				int len = 0;
				while (-1 != (len = bis.read(flush))) {
					bos.write(flush, 0, len);
				}
				bos.flush();
				bis.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		SplitFile sp = new SplitFile("D:\\aa\\b\\新建 Microsoft Excel 工作表.xlsx", 50, "d:/aa");
		System.out.println(sp.length);
		sp.split();
		sp.merge("d:/aa/新建 Microsoft Excel 工作表.xlsx");
	}

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-01-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 通过RandomAccessFile对象进行文件分割与合并
    • SplitFile类的初始化
      • 类包含的变量
      • 构建函数
    • 分割文件
      • 分割文件实现细节
    • 合并文件
      • 采用迭代器以及合并流进行文件合并
      • 采用普通方法合并文件
    • 主函数
      • 完整代码
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档