这里将介绍,将MP3格式的一个文件,分割成几个部分,然后,在使用序列流SequenceInputStream流将这几个部分合并成一个完整的MP3格式的文件。
接下来先介绍一下序列流SequenceInputStream:
SequenceInputStream:序列流,作用就是将多个读取流合并成一个读取流。实现数据合并。
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
这样做,可以更方便的操作多个读取流,其实这个序列流内部会有一个有序的集合容器,用于存储多个读取流对象。
该对象的构造函数参数是枚举,想要获取枚举,需要有Vector集合,但不高效。需用ArrayList,但ArrayList中没有枚举,只有自己去创建枚举对象。
但是方法怎么实现呢?因为枚举操作的是具体集合中的元素,所以无法具体实现,但是枚举和迭代器是功能一样的,所以,可以用迭代替代枚举。
合并原理:多个读取流对应一个输出流。
切割原理:一个读取流对应多个输出流。
具体代码如下:
import java.io.*;
import java.util.*;
public class SplitFile {
public static void main(String[] args) throws IOException {
// splitFile();
mergeFile();
}
/*
* 切割文件
*/
public static void splitFile() throws IOException{
//创建输入流,关联一个图片文件
FileInputStream fis = new FileInputStream("D:\\光明.mp3");
FileOutputStream fos = null;//创建输出流,设为空,以便在循环中创建多个文件使用
byte[] b = new byte[1024*2000];
int len = 0;
int count=1;//因为切割完的文件通常都有规律的。为了简单标记规律使用计数器。
while((len=fis.read(b))!=-1){
//创建存入的文件,此文件随意设置,因为是没有实际作用的。
//切割成多个文件,文件名是变化的,因此用count记录变化。
fos = new FileOutputStream("C:\\splitfiles\\光明"+(count++)+".part");
fos.write(b,0,len);
fos.close();//需在循环中关闭输出流
}
fis.close();
}
/*
*合并文件 (将切割的几个文件内容合并写入到一个新的文件光明.mp3中)
*/
public static void mergeFile() throws IOException{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
File f = new File("C:\\splitfiles");
for(int x=1;x<=f.list().length;x++){
//添加(流)元素:文件
al.add(new FileInputStream("C:\\splitfiles\\光明"+x+".part"));
}
final Iterator<FileInputStream> it = al.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){
@Override
public boolean hasMoreElements() {
return it.hasNext();
}
@Override
public FileInputStream nextElement() {
return it.next();
}
};
//创建序列流,对多个流进行合并,读取
SequenceInputStream sis = new SequenceInputStream(en);
//创建输出流,关联写入文件(若不存在则创建)
FileOutputStream fos = new FileOutputStream("C:\\光明.mp3");
byte[] buf = new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();//关闭所有流
}
}