黑马程序员-文件的切割与合并

来源:互联网 发布:在淘宝上开店哪些缴费 编辑:程序博客网 时间:2024/04/25 14:20


------- <a  target="blank">android培训</a>、<a  target="blank">java培训</a>、期待与您交流! ----------

package test;

import java.io.File;
import java.io.FileFilter;
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;


/**
 * 需求:将一个媒体文件切割成若干块,保存在一个文件目录,并且带上配置文件记录信息,以便合并之用
 * 
 * 思路: 
 * 
 * 切割文件: 
 * 1.用文件字节流读取,搞一个指定大小的缓冲区,一旦缓冲区装满就将缓冲区的内容输出到一个文件中。
 * 2.再接着读取源数据撞到缓冲区,下次输出的时候要改变目的,所有就有了多个输出流。 3.最后要创建一个配置文件,将源文件名和产生的文件碎片个数存储下来。
 * 4.切割文件就是一个读取流对应多个输出流。
 * 
 * 合并文件:
 * 1.首先要获取目录下的配置文件信息,获取合成后的文件名,还有碎片文件的个数。
 * 2.遍历目录,获取碎片文件的个数,做一个健壮性判断,配置信息中的碎片文件个数是否等于遍历数来的个数,如果不等,报异常,结束程序。
 * 3.然后就是读取碎片文件,以字节流读取,多个读取字节流对应一个字节输入流。因为数据存放的文件只有一个,合并嘛。
 * 
 */


public class Test4 {
public static void main(String[] args) throws IOException {
//指定要切割的文件路径名
File file = new File("e:\\Demo\\sound.mp3");
//调用切割函数
SplitFile(file);
//指定碎片文件的父级目录
File dir = new File("e:\\Demo\\partfile");
//合并发文件
megerFile(dir);
}
/**
*  切割文件函数:给我一个文件对象,给你切切切
*/
public static void SplitFile(File file) throws IOException {
//记录每次读取的字节数,便于准确写入,如果没有记录值,可能最后一次读取的数据装不满字节数组,而写入的数据为一整个数组,会使文件变大,当然文件不会损坏。
int len;
//File file = new File("e:\\Demo\\sound.mp3");
//创建一个目录的引用,用于放置切出的碎片文件,并封装成对象
File dir = new File("e:\\Demo\\partfile");
//如果目录不存在就创建
if(!dir.exists())
dir.mkdirs();
//System.out.print(dir.getAbsolutePath());
//定义一个字节数组缓冲区,也是每一个碎片文件的大小
byte[] buf = new byte[1024*1024];
//创建一个文件字节读取流,指向传进来的对象文件
FileInputStream fis = new FileInputStream(file);
//创建一个文件字节输出流的引用为null,因为输出流的地址会不同,正如一个读取流对应多个输出流
FileOutputStream fos = null;
int count = 0;
//疯狂读取,读一次满之后,写入数据,同时输出流的对象也变化,在++count上体现
while ((len = (fis.read(buf))) != -1) {
fos = new FileOutputStream("e:\\Demo\\partfile\\" + (++count)
+ ".part");
fos.write(buf, 0, len);
//刷新流
fos.flush();
}
//提取源文件的文件名
String filename = file.getName();
//定义一个properties集合,用来装键值对信息
Properties prop = new Properties();
//存储文件名
prop.setProperty("filename", filename);
//存储碎片文件个数
prop.setProperty("partcount", count + "");
//输出流引用指向一个文件对象
fos = new FileOutputStream("e:\\Demo\\partfile\\config.properties");
//输出配置文件
prop.store(fos, "");
//关闭资源
fos.close();
fis.close();
}


/**
* 合并文件函数:传一个文件目录给我,我获取目录中的指定文件=和配置文件,按配置文件信息将其合成。
*/
public static void megerFile(File dir) throws IOException {
//检测传给我的目录是否存在
if (!dir.isDirectory() || !dir.exists())
throw new RuntimeException("文件目录不存在,你忽悠我!");
//遍历,刷选出配置文件
File[] files = dir.listFiles(new SuffixFilter(".properties"));
//如果配置文件不唯一,报错
if (files.length != 1)
throw new RuntimeException("配置信息不存在或不唯一,你又忽悠我!");
//将配置文件封装成对象
File config = files[0];
//用文件字节读取流指向配置文件
FileInputStream fis = new FileInputStream(config);
//将配置信息载入properties集合
Properties pop = new Properties();
pop.load(fis);
//获取配置信息中的源文件名
String filename = pop.getProperty("filename");
//获取配置信息中碎片文件爱你个数
int partcount = Integer.parseInt(pop.getProperty("partcount"));
//遍历,获取目录中的碎片文件
File[] partFiles = dir.listFiles(new SuffixFilter(".part"));
//检测判断,如果遍历碎片个数与配置信息中的不符,报错
if (partFiles.length != partcount)
throw new RuntimeException("碎片文件异常,你老忽悠我!");
//创建一个arraylist集合,用来装字节流对象
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
//File[] partfiles = dir.listFiles(new SuffixFilter(".part"));
//创建读取字节流与碎片文件对象相对应,并添加到集合中
for (int i = 0; i < partcount; i++)
al.add(new FileInputStream(partFiles[i]));
//获取al的枚举,类似迭代器
Enumeration<FileInputStream> en = Collections.enumeration(al);
//将集合中的流对象序列化
SequenceInputStream sis = new SequenceInputStream(en);
//定义输出文件的位子,封装成file
File file = new File(dir.getParentFile(),filename);
//用一个输出流指向目的地
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024*1024];
int len = 0;
//有序的读取每个碎片文件并写入
while ((len = sis.read(buf)) != -1)
fos.write(buf, 0, len);
//关闭流资源
fos.close();
sis.close();
}
}
//文件过滤器继承FileFilter
class SuffixFilter implements FileFilter {
private String suffix;
SuffixFilter(String suffix) {
this.suffix = suffix;
}
@Override
public boolean accept(File file) {
return file.getName().endsWith(suffix);
}
}


------- <a  target="blank">android培训</a>、<a  target="blank">java培训</a>、期待与您交流! ----------

0 0
原创粉丝点击