Ok,今天写个文件合并器。依然是Java IO 的应用。
文件合并器就是把切碎后的文件恢复成原来的样子。基本思路就是把碎片文件流放到一个合并流中,然后再写到另外一个流中即可。Java IO 里有一个SequenceInputStream这样的对象。
它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。---Java文档
原文件的有关信息可以从properties 文件中读取。在读取过程中涉及到一个文件过滤器的概念,就是只选择后缀名为.part的文件。Java里面有一个FilenameFilter这样的接口。我们可以实现这个接口的accept方法来实现自己的过滤规则.
知道了这些,实现起来就比较简单了。具体过程我们看源码:
/*
*Mar 28, 2013
*Copyright(c)JackWang
*All rights reserve
*@Author <a href="mailto:wangchengjack@163.com">JackWang</a>
*/
package com.myjava.function;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
import com.myjava.filter.suffixFilter;
import com.myjava.myexception.DataErrorException;
import com.myjava.myexception.NoSuchFileException;
/**
* 需求:合并文件
* 思路:用SequenceInputStrem将切割的文件流合并为一个存储起来
* 文件的相关信息从propreties文件中读取
* @author WangCheng
*
*/
public class MergeFile {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
File dir = new File("I:"+File.separator+"PartFiles"); //切割文件绝对路径
boolean result = mergeFile(dir);
System.out.println(result);
}
public static boolean mergeFile(File dir) throws IOException {
//参数合法性检查
if(!dir.exists()){
throw new NoSuchFileException("文件夹不存在!!!");
}
File[] files = dir.listFiles(new suffixFilter(".part")); //得到碎片文件对象
File[] propFiles = dir.listFiles(new suffixFilter(".properties")); //得到配置文件
Properties prop = null;
prop = getPropertiesValue(dir,propFiles[0].getName());
if (propFiles.length != 1) {
throw new DataErrorException("配置文件有错误!");
}
if (files.length != Integer.parseInt(prop.getProperty("count"))) {
throw new DataErrorException("碎片文件不完整!");
}
// for (File file : files) {
// System.out.println(file.getName());
// }
Collection<FileInputStream> list = new ArrayList<FileInputStream>();
for (File file : files) {
list.add(new FileInputStream(file));
}
Enumeration<FileInputStream> en = Collections.enumeration(list);
//合并流
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream(new File(dir,prop.getProperty("fileName")));
int len = 0;
byte[] buff = new byte[1024*1024];
while((len = sis.read(buff))!=-1){
fos.write(buff,0,len);
}
sis.close();
fos.close();
return true;
}
public static Properties getPropertiesValue(File dir,String name) throws IOException {
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(new File(dir,name));
prop.load(fis);
return prop;
}
}
文件过滤器的实现:
/**
*Mar 28, 2013
*Copyright(c)JackWang
*All rights reserve
*@Author <a href="mailto:wangchengjack@163.com">JackWang</a>
*/
package com.myjava.filter;
import java.io.File;
import java.io.FilenameFilter;
public class suffixFilter implements FilenameFilter {
private String suffix;
public String getSuffix() {
return suffix;
}
/**
* @param suffix
*/
public suffixFilter(String suffix) {
super();
this.suffix = suffix;
}
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return name.endsWith(this.getSuffix());
}
}
到此,文件合并器就完成了。