import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/*
* 切割文件
* 一个源文件,切割成多个目的文件
* (一个输入流,多个输出流)
*/
public class splitFileDemo {
private static final int SIZE = 1024*1024;
public static void main(String[] args) throws IOException {
File dir = new File("6.mp3");
splitFile_2(dir);
}
private static void splitFile_2(File dir) throws IOException {
//1,建立一个字节读取流对象关联要被切割的文件
FileInputStream fis = new FileInputStream(dir);
//2,建立一个缓冲区,用来存放指定大小的文件,进行切割。这里是1M大小
byte[] buff = new byte[SIZE];
//3,建立一个文件夹,用来存放切割后文件。如果不存在就自己创建
File file = new File("C:\splitFile");
if(!file.exists()){
file.mkdirs();//创建多层文件夹
}
int len = 0;
int count = 0;
FileOutputStream fos = null;
while((len = fis.read(buff))!=-1){
count++;
/*每1M该文件大小就存放一份,因为重名会被覆盖
*所以定义一个变量count,使每次存放到硬盘的文件不被覆盖
*/
fos = new FileOutputStream(new File(file,count+".part"));
fos.write(buff,0,len);
//每写入一个碎片文件记得关闭流
fos.close();
}
/*
* 4,因为要记录切割文件的文件名,和文件个数,为了将其保存起来,方便合并
* 用properties集合,然后将其存储到文件中
*/
Properties pro = new Properties();
//将要被切割的文件名存放到集合中
pro.setProperty("filename", dir.getName());
//将碎片文件个数信息存放到集合中,因为包含信息本身文件 ,所以count+1。
//Property集合存放的是字符串信息,所以要将整数转换为字符串
pro.setProperty("partcount", Integer.toString(count+1));
//定义一个输出流,用来将信息数据写到文件中
fos = new FileOutputStream(new File(file,".properties"));
//将信息保存到文件中
pro.store(fos , "info");
//关闭流
fos.close();
fis.close();
}}
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.Collections;
import java.util.Enumeration;
import java.util.Properties;
/*
* 合并文件
* 多个输入流一个输出流
*
*/
public class MergeFileDemo2 {
private static final int SIZE = 1024*1024;
public static void main(String[] args) throws IOException {
//建立需要合并的文件对象
File dir = new File("c:\splitFile");
mergeFile_2(dir);
}
public static void mergeFile_2(File dir) throws IOException {
//1,获取所要合并文件的信息
===========================================================
//我们需要获取所要合并的文件信息,
如文件的个数,所切割的文件名。那就用到过滤
File[] files = dir.listFiles(new FileBySuffix(".properties"));
files里有且只有一个该信息文件,如果多了或没有,抛异常
if(files.length!=1){
throw new RuntimeException("你要合并的文件信息不符合标准");
}
//成功获得信息就进行下一步,获取信息内容
Properties pro = new Properties();
//载入文件
pro.load(new FileInputStream(files[0]));
int count =Integer.parseInt(pro.getProperty("partcount"));
//同样要做健壮性判断,过滤剩下part文件,也就是碎片文件
File[] partfile = dir.listFiles(new FileBySuffix(".part"));
if(partfile.length!=count-1){
throw new RuntimeException("碎片文件个数不对");
}
for(int i = 0;i<partfile.length;i++){
al.add(new FileInputStream(partfile[i]));
}
*/
//2,将碎片文件与流相关联,将流存储到集合中,以便合并。
==============================================================
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int i = 1;i<count;i++){
al.add(new FileInputStream(new File(dir,i+".part")));
}
//枚举该集合的的元素,用于序列流的传入参数
Enumeration<FileInputStream> en = Collections.enumeration(al);
//3,合并过程
==============================================================
//序列流 用于合并几个输入流,然后用一个输出流输出到文件中
SequenceInputStream sis = new SequenceInputStream(en);
//获取切割前的文件名,作为合并后的文件名。
String name = pro.getProperty("filename");
//建立一个输出流对象,用于输出到相应的文件中
FileOutputStream fos = new FileOutputStream(new File(dir,name));
byte [] buff =new byte[SIZE];
int len = 0;
while((len=sis.read(buff))!=-1){
fos.write(buff,0,len);
fos.flush();
}
//关闭流
fos.close();
sis.close();
}}
//过滤器
import java.io.File;
import java.io.FilenameFilter;
public class FileBySuffix implements FilenameFilter {
private String suffix;
public FileBySuffix(String suffix) {
super();
this.suffix = suffix;
}
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}}