SequenceInputStream可以看做是多个InputStream对象的有序集合。当一个InputStream对象的数据读取完后,它会自动取出下一个InputStream对象进行读取,直到所有的InputStream对象都读取完为止。
利用这个特点,我们来编写一个文件分割、合并工具。
使用说明:
SequenceDemo [Option] [filePath] [number]
Option:
-c : 表示要合并文件
-s : 表示要分割文件
filePath:
指定一个文件路径
number:
指定单个文件大小或文件数量
如:
java cls.SequeceDemo -s F:\QQ.exe 102400
表示将QQ.exe分割成多个文件大小为102400字节的小文件。
java cls.SequeceDemo -m F:\QQ.exe 13
表示将已经被分割好的13个QQ.exe文件合并成一个整文件。
注意,构造SequenceOutputStream对象时需要一个Enumeration对象的引用做为参数。Enumeration是一个接口,我们必须实现这个接口中的hasMoreElements()方法和nextElement()方法。
完整代码:
package cls;
import java.io.*;
import java.util.*;
public class SequenceStreamDemo
{
public static void main(String[] args) throws Exception
{
switch(args[0].charAt(1))
{
case 's': // 分割文件
{
SequenceStreamDemo.seperate(args[1],Long.parseLong(args[2]));
break;
}
case 'm': // 合并文件
{
SequenceStreamDemo.merge(args[1],Integer.parseInt(args[2]));
break;
}
default: // 参数输入错误
{
System.out.println("非法参数");
break;
}
}
}
/* 合并文件
* fileName : 文件名
* amount : 要合并的小文件的数量
**/
public static void merge(String fileName,int amount) throws Exception
{
// 创建合并后的文件
File file = new File(fileName);
FileOutputStream fis = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fis);
// 将多个小文件对象保存在List中
List<InputStream> list = new ArrayList<InputStream>();
for(int i = 0 ; i < amount ; ++i)
{
File f = new File(fileName + "_" + i);
list.add(new FileInputStream(f));
}
final Iterator<InputStream> it = list.iterator();
// 构建Enumeration对象
Enumeration<InputStream> em = new Enumeration<InputStream>()
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public InputStream nextElement()
{
return it.next();
}
};
// 使用SequenceInputStream合并文件
BufferedInputStream bis = new BufferedInputStream(new SequenceInputStream(em),8192);
int data;
while((data = bis.read()) != -1)
{
bos.write(data);
}
bis.close();
bos.flush();
bos.close();
System.out.println("合并完成");
}
/* 分割文件
* fileName : 文件名
* size : 单个文件的大小
**/
public static void seperate(String fileName,long size) throws Exception
{
File file = new File(fileName);
long number;
// 计算分割后的文件数量
if(0 == file.length() % size)
{
number = file.length() / size;
}
else
{
number = file.length() / size + 1;
}
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
// 开始分割
byte[] buf = new byte[1];
for(int i = 0 ; i < number ; ++i)
{
FileOutputStream fos = new FileOutputStream(new File(fileName + "_" + i));
BufferedOutputStream bos = new BufferedOutputStream(fos);
long curSize = 0L;
while(bis.read(buf) != -1)
{
bos.write(buf);
curSize++;
if(curSize == size) // 已经分割成了一个小文件
{
bos.flush();
bos.close();
break;
}
}
if(curSize < size) // 打包剩下的数据
{
bos.flush();
bos.close();
break;
}
}
System.out.println("分割完成");
}
}