Java文件切割与合并二之File开道

62 篇文章 3 订阅
12 篇文章 0 订阅

目的:把一个磁盘中的文件进行切割成若干份文件,然后合并这些文件。

详细请点击:点击打开链接

思想一:

使用IO技术读取文件,没读1M文件就重新new一个文件,然后把数据放入新的文件中。注意:1M=1024*104字节,因为java的IO只有两大家族,一个为字节流,一个为字符流,如果选择字符流,那么就只能读取纯文本文件,不然会把数据丢失。于是选择字节流,那么字节流就只能用字节数组读取数据。不要问我为什么不用int数组读的问题,因为java的字节流只提供了字节数组的方法,其他的可以自己造(可以查看API)。

简易代码如下:

package outIn2.fileCutAndMerge2;

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

import javax.swing.JFileChooser;

public class FileSplit {
	public static int splitNumber = 1024 * 1024;// 一次切割1M

	public static void main(String[] args) {
		JFileChooser jf = new JFileChooser();
		int result = jf.showOpenDialog(null);
		File srcFile = null;
		File dirFile = null;
		if (result == JFileChooser.APPROVE_OPTION) {
			srcFile = jf.getSelectedFile();
			dirFile = new File("d:/ex/a/splitFile");
			splitFile(srcFile, dirFile);
		}
	}

	/*
	 * splitFile-切割文件
	 * srcFile-源文件
	 * dirFile-目标放置文件夹
	 */
	public static void splitFile(File srcFile, File dirFile) {
		FileInputStream fin = null;
		FileOutputStream fout = null;
		// 使用File开道
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}
		try {
			fin = new FileInputStream(srcFile);
			String name1 = dirFile.getAbsoluteFile() + "/";
			int count = 1;
			fout = new FileOutputStream(name1 + count + ".part");
			byte[] bys = new byte[splitNumber];
			int len = 0;
			while ((len = fin.read(bys)) != -1) {
				fout.write(bys, 0, len);
				fout.close();
				if (len == splitNumber) {
					fout = new FileOutputStream(name1 + (++count) + ".part");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fout != null) {
				try {
					fout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fin != null) {
				try {
					fin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}



思想二:

使用配置文件,将分割文件的绝对路径保存在配置文件中,那么下次合并时就变得简单了。

Java代码:

package outIn2.fileCutAndMerge2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;

import javax.swing.JFileChooser;

public class FileSplit {
	public static int splitNumber = 1024 * 1024;// 一次切割1M

	public static void main(String[] args) {
		JFileChooser jf = new JFileChooser();
		int result = jf.showOpenDialog(null);
		File srcFile = null;
		File dirFile = null;
		if (result == JFileChooser.APPROVE_OPTION) {
			// 切割文件
			srcFile = jf.getSelectedFile();
			dirFile = new File("d:/ex/a/splitFile");// 可以自定义
			splitFile(srcFile, dirFile);
			// 合并文件
			mergeFiles(dirFile, new File("d:/ex/b/splitFile"),
					srcFile.getName());
		}
	}

	/*
	 * splitFile-切割文件
	 * srcFile-源文件,可以得到源文件路径
	 * dirFile-目标放置文件夹,可以得到目标放置文件夹路径
	 */
	public static void splitFile(File srcFile, File dirFile) {
		BufferedInputStream bin = null;
		BufferedOutputStream bout = null;
		BufferedOutputStream pout = null;
		Properties pro = new Properties();
		// 使用File开道
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}
		try {
			// new出切割文件的读写流
			bin = new BufferedInputStream(new FileInputStream(srcFile));
			int count = 1;
			String name1 = dirFile.getAbsoluteFile() + "/";
			String name2 = name1 + count + ".part";
			bout = new BufferedOutputStream(new FileOutputStream(name2));
			/*
			 *  配置文件的写流,
			 *  写流是单独开一个,
			 *  因为要生成多个文件,说以不能用fout。
			 */
			pout = new BufferedOutputStream(new FileOutputStream(name1
					+ "mySplitPro.Properties"));
			/*
			 *  使用读写流
			 */
			byte[] bys = new byte[splitNumber];
			int len = 0;
			while ((len = bin.read(bys)) != -1) {
				bout.write(bys, 0, len);
				bout.close();
				pro.setProperty("" + count, name2);
				name2 = name1 + (++count) + ".part";
				if (len == splitNumber) {
					bout = new BufferedOutputStream(new FileOutputStream(name2));
				}
			}
			/*
			 *  数据读取完了,就应该保存配置文件
			 *  comment-评论记录文件的个数,
			 *  下次访问时,如果个数不对,
			 *  那么就不给用户合并文件。
			 */
			pro.store(pout, "" + (count - 1));
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (pout != null) {
				try {
					pout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bout != null) {
				try {
					bout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bin != null) {
				try {
					bin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/*
	 * mergeFiles-合并文件
	 * dirFile-目录文件夹,可以得到目录文件夹路径
	 * newFile-合成新文件,可以得到合成新文件的路径
	 */
	public static boolean mergeFiles(File dirFile, File parentPath,
			String fileName) {
		// File开道
		if (!parentPath.exists()) {
			parentPath.mkdirs();
		}
		parentPath = new File(parentPath.getAbsolutePath(), fileName);
		Properties pro = new Properties();
		BufferedReader br = null;
		BufferedInputStream[] bins = null;
		SequenceInputStream se = null;
		BufferedOutputStream bout = null;
		try {
			/*
			 * 从配置文件中读取数据的准备
			 */
			br = new BufferedReader(new FileReader(dirFile.getAbsoluteFile()
					+ "/mySplitPro.Properties"));
			String num = "";
			String str = br.readLine();
			for (int i = 1; i < str.length(); i++) {
				num += str.charAt(i);
			}
			int count = 0;
			try {
				count = Integer.parseInt(num);
			} catch (Exception e) {
				System.out.println("文件个数解析异常");
			}
			pro.load(br);
			/*
			 * 构造序列流
			 */
			ArrayList<BufferedInputStream> al = new ArrayList<BufferedInputStream>();
			bins = new BufferedInputStream[count];
			for (int i = 1; i <= bins.length; i++) {
				try {
					bins[i - 1] = new BufferedInputStream(new FileInputStream(
							pro.getProperty("" + i)));
				} catch (Exception e) {
					return false;
				}
				al.add(bins[i - 1]);
			}
			Enumeration<BufferedInputStream> en = Collections.enumeration(al);
			se = new SequenceInputStream(en);
			bout = new BufferedOutputStream(new FileOutputStream(parentPath));
			/*
			 * 序列流读取数据,
			 * bout写数据。
			 */
			byte[] bys = new byte[splitNumber];
			int len = 0;
			while ((len = se.read(bys)) != -1) {
				bout.write(bys, 0, len);
			}
		} catch (Exception e) {
		} finally {
			for (int i = 0; i < bins.length; i++) {
				if (bins[i] != null) {
					try {
						bins[i].close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			if (se != null) {
				try {
					se.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bout != null) {
				try {
					bout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return true;
	}

}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值