package com.stella;
import java.io.Closeable;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;
/**
* 切割与合并文件
* @author Administrator
*
*/
public class SplitAndCombineFile {
public static void main(String[] args) throws IOException {
File file = new File("E:\\多生产者多消费者.wmv");
//File parentFile = getDiretory(file);
//initPropertiesFile(parentFile);
//splitFile(file, "rar");
combineFiles(file);
}
/**
* 获取配置文件
* @return
*/
public static File getPropertiesFile(File file){
//遍历文件目录找配置文件
File parentFile = getDiretory(file);
File[] files = parentFile.listFiles();
for(File f : files){
if(f.isFile() && fileSuffixFilter(f,"properties")){
return f;
}
}
return null;
}
/**
* 程序启动时加载配置文件
* @param fileDir配置文件
* @throws IOException
*/
public static void initPropertiesFile(File file) throws IOException{
//思路
//1.查看此配置文件是否存在,如果存在删除,如果不存在创建,然后加载配置信息
if(file != null && !file.exists()){
file.createNewFile();
}else{
//如果文件存在,则删除该文件,重新创建一个
file.delete();
initPropertiesFile(file);
}
}
/**
* 获取存切割了的文件和配置文件的目录
* @param file原文件的目录
* @return
*/
public static File getDiretory(File file){
//思路
//1根据原文文件的目录找出它的父目录即是我们所需的文件目录
return file.getAbsoluteFile().getParentFile();
}
/**
* 文件后缀名过滤器
* @param file
* @return
*/
public static boolean fileSuffixFilter(File file,final String suffix){
return new FileFilter() {
@Override
public boolean accept(File f) {
return f.getName().endsWith(suffix);
}
}.accept(file);
}
/**
* 合并文件
* @param filesDir 传入原文件
*/
public static void combineFiles(File file){
//思路
//1.根据指定目录找到配置文件,查找要合并的碎片文件的后缀名,以及合并以后的后缀名
ArrayList<FileInputStream> fileList = new ArrayList<FileInputStream>();
File propertiesFile = getPropertiesFile(file);
if(propertiesFile == null){
throw new RuntimeException("配置文件找不到!");
}
Properties properties = new Properties();
SequenceInputStream sInputStream = null;
FileOutputStream fileOutputStream = null;
try {
properties.load(new FileInputStream(propertiesFile));
String splitSuffix = properties.getProperty("splitFileSuffix");
File[] files = file.getParentFile().listFiles();
for(File f : files){
if(f.isFile() && fileSuffixFilter(f, splitSuffix)){
fileList.add(new FileInputStream(f));
}
}
sInputStream = new SequenceInputStream(Collections.enumeration(fileList));
fileOutputStream = new FileOutputStream(new File(file.getParentFile().getName() + "\\copy." + properties.getProperty("fileSuffix")));
byte[] bytes = new byte[1024*1024*10];
int num = 0;
while((num = sInputStream.read(bytes)) != -1){
fileOutputStream.write(bytes, 0, num);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
closeStream(sInputStream,fileOutputStream);
}
//2.创建ArrayList集合,将碎片文件装入集合
//3.创建SequenceInputStream,用Collections.enumeration(集合)
}
/**
* 切割文件
* @param filePath 要进行切割的文件
* @param splitFileSuffix 切割后文件的后缀名
*/
public static void splitFile(File filePath, String splitFileSuffix){
//思路
//1.先对filePath进行处理,检查它是不是一个文件,如果是文件,则进行切割,如果不是抛出异常
FileOutputStream fileOutput = null;
FileInputStream fileInput = null;
if(!filePath.isFile()){
throw new RuntimeException("这不是一个文件!");
}
try {
fileInput = new FileInputStream(filePath);
byte[] bytes = new byte[1024*1024];
int byteNum = 0;
int splitFileNum = 1;
File parentFile = getDiretory(filePath);
String parentFilePath = parentFile.getAbsolutePath();
while((byteNum = fileInput.read(bytes)) != -1){
//这里把切割以后的文件存到和原文件相同的文件夹
fileOutput = new FileOutputStream(parentFilePath + "\\" + splitFileNum ++ + "." + splitFileSuffix);
fileOutput.write(bytes, 0, byteNum);
}
//3.更新文件的配置信息
Properties properties = new Properties();
properties.setProperty("splitFileSuffix", splitFileSuffix);
String fileName = filePath.getName();
properties.setProperty("fileSuffix", fileName.substring(fileName.lastIndexOf(".") + 1));
//这里减1是因为上面是++最后多加了一次
properties.setProperty("splitFileNum",String.valueOf(splitFileNum - 1));
//将properties保存到配置文件里
properties.store(new FileOutputStream(new File(parentFilePath + "\\" + "splitfile.properties")), "addpropertiesconfig");
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("文件找不到!");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("流异常!");
}finally{
//关闭所有打开的流
closeStream(fileOutput,fileInput);
}
}
/**
* 关闭打开的流
* @param closeables 不定参列表
*/
public static void closeStream(Closeable...closeables){
for(Closeable closeable : closeables){
try {
if(closeable != null){
closeable.close();
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("流关闭异常!");
}
}
}
}