描述

文件分割与合并是一个常见需求,比如:通过webservice接口发送大文件时,可以先分割成分片小块,然后根据数据块起始位置写成完整文件。

代码示例
package com.gdie.jxw.gwbl.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

import org.apache.commons.codec.binary.Base64;

public class FileSliceUtil {

	// 文件处理
	public static void fileHandle() throws IOException {
		// 文件拆成分片
		String filePath = "D:\\work\\测试文档.DOCX";
		// 文件块大小,单位byte
		long blockSize = 512000;
		// 文件块起始位置
		long dataIndex = 0;
		Base64 base64 = new Base64();
		File tempFile = new File(filePath);
		InputStream in = new FileInputStream(tempFile);
		// 文件大小
		long fileSize = in.available();
		System.out.println(">>文件大小:" + fileSize);
		// 循环读取文件块内容
		while (dataIndex < fileSize) {
			// 判断数据起始位置加上读取文件块大小是否超出文件大小,如果超出,重新计算文件块大小
			if ((dataIndex + blockSize) > fileSize) {
				blockSize = fileSize - dataIndex;
			}
			byte[] fileBlockContent = new byte[(int) blockSize];
			try {
				in.read(fileBlockContent, 0, (int) blockSize);
			} catch (IOException e2) {
				e2.printStackTrace();
			}
			String fileContent = base64.encodeToString(fileBlockContent);
			// 模拟分块写入
			sliceInsert(fileContent, dataIndex);
			dataIndex = dataIndex + blockSize;
		}
		// 文件分片写入
		System.out.println("分片结束");
	}

	/**
	 * 分片插入
	 * @param content 分片内容
	 * @param dataIndex 插入位置开始
	 */
	public static void sliceInsert(String content, long dataIndex) {
		try {
			System.out.println("开始写入了");
			byte[] contentInBytes = Base64.decodeBase64(content);
			File tmp = File.createTempFile("tmp", null);
			String fileName = "D://work//分片组成的文档.DOCX";
			tmp.deleteOnExit();
			try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
					FileOutputStream tmpOut = new FileOutputStream(tmp);
					FileInputStream tmpIn = new FileInputStream(tmp)) {
				raf.seek(dataIndex);
				byte[] buf = new byte[64];
				int hasRead = 0;
				while ((hasRead = raf.read(buf)) > 0) {
					tmpOut.write(buf, 0, hasRead);
				}
				raf.seek(dataIndex);
				raf.write(contentInBytes);
				while ((hasRead = tmpIn.read(buf)) > 0) {
					raf.write(buf, 0, hasRead);
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws IOException {
		fileHandle();
	}

}