您将一个文件分割为数个文件,接下来要将之再度组合还原为原来的文件,最基本的作法是使用数个
FileInputStream来开启分割后的文件,然后一个一个文件的读取,并连续写入至同一个FileOutputStream中,在这中间,您必须
要自行判断每一个分割文件的读取是否完毕,如果完毕就换读取下一个文件。
如果您使用SequenceInputStream就不用这么麻烦,SequenceInputStream可以看作是数个
InputStream对象的组合,当一个InputStream对象的内容读取完毕后,它就会取出下一个InputStream对象,直到所有的
InputStream对象都读取完毕为止。
下面这个程序是SequenceInputStream的使用示范,它可以将指定的文件进行分割,也可以将分割后的文件还原为一个文件:
package onlyfun.caterpillar;
import java.util.*; import java.io.*;
public class SequenceStreamDemo { public static void main(String[] args) { try { // args[0]: 指定分割(s)或连接(c) switch (args[0].charAt(1)) { case 's': // args[1]: 每个分割文件的大小 int size = Integer.parseInt(args[1]); // args[2]: 指定要被分割的文件名称 seperate(args[2], size); break; case 'c': // args[1]: 指定要被组合的文件个数 int number = Integer.parseInt(args[1]); // args[2]: 组合后的文件名称 concatenate(args[2], number); break; } } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "Using: java UseSequenceStream [-s/-c]" + " (size/number) filename"); System.out.println("-s: 分割文件\n-c: 组合文件"); } catch(IOException e) { e.printStackTrace(); } }
// 分割文件 public static void seperate(String filename, int size) throws IOException { FileInputStream fileInputStream = new FileInputStream(new File(filename)); BufferedInputStream bufInputStream = new BufferedInputStream(fileInputStream);
byte[] data = new byte[1]; int count = 0; // 从原文件大小及指定分割的大小 // 决定要分割为几个文件 if(fileInputStream.available() % size == 0) count = fileInputStream.available() / size; else count = fileInputStream.available() / size + 1; // 开始进行分割 for(int i = 0; i < count; i++) { int num = 0; // 分割的文件加上底线与编号 File file = new File(filename + "_" + (i + 1)); BufferedOutputStream bufOutputStream = new BufferedOutputStream( new FileOutputStream(file)); while(bufInputStream.read(data) != -1) { bufOutputStream.write(data); num++; if(num == size) { // 分割出一个文件 bufOutputStream.flush(); bufOutputStream.close(); break; } } if(num < size) { bufOutputStream.flush(); bufOutputStream.close(); } } System.out.println("分割为" + count + "个文件"); }
// 连接文件 public static void concatenate(String filename, int number) throws IOException { // 收集文件用的List List<InputStream> list = new ArrayList<InputStream>(); for(int i = 0; i < number; i++) { // 文件名必须为底线加上编号 File file = new File(filename + "_" + (i+1)); list.add(i, new FileInputStream(file)); } final Iterator<InputStream> iterator = list.iterator(); // SequenceInputStream 需要一个Enumeration对象来建构 Enumeration<InputStream> enumation = new Enumeration<InputStream>() { public boolean hasMoreElements() { return iterator.hasNext(); }
public InputStream nextElement() { return iterator.next(); } }; // 建立SequenceInputStream // 并使用BufferedInputStream BufferedInputStream bufInputStream = new BufferedInputStream( new SequenceInputStream(enumation), 8192);
BufferedOutputStream bufOutputStream = new BufferedOutputStream( new FileOutputStream(filename), 8192);
byte[] data = new byte[1]; // 读取所有文件数据并写入目的地文件 while(bufInputStream.read(data) != -1) bufOutputStream.write(data);
bufInputStream.close(); bufOutputStream.flush(); bufOutputStream.close(); System.out.println("组合" + number + "个文件 OK!!"); } }
分割文件时的范例如下:
java onlyfun.caterpillar.SequenceStreamDemo -s 1048576 test.zip
分割为6个文件
|
组合文件时的范例如下:
java onlyfun.caterpillar.SequenceStreamDemo -c 6 test.zip
组合6个文件 OK!!
|
|