------- <a target="blank">android培训</a>、<a target="blank">java培训</a>、期待与您交流! -------
package it.heima.mylog;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
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 FileSpliter {
/*
* 关键词:文件切割器+配置文件
*
* ObjectOutputStream&&ObjectInputStream对象的序列化和反序列化,Serializable序列化标记接口
*/
/* 文件切割器 */
private static File file;
private static File dir;
public static void main(String[] args) {
file = new File("c:\\1.mp3");
dir = new File("c:\\partfiles");
try {
splitFile(file);
mergeFile(dir);
} catch (IOException e) {
e.printStackTrace();
}
}
// 切割==================================
private static void splitFile(File file) throws IOException {
// 首先要读取流关联一个源文件啊
FileInputStream fis = new FileInputStream(file);
// 定义一个1M的缓冲区
byte[] buf = new byte[1024*1024];
// 创建目的地,因为是切割文件,所以目的地肯定不是一个,不唯一
FileOutputStream fos = null;
int len = 0;
int count = 1;
/*
* 切割文件时,必须记录住被切割的文件名,以及切割出来的碎片文件的个数,以便于合并。
* 为了记住这个信息,可以使用键值对的形式存储在配置文件中。用到了Properties对象。
*/
Properties prop = new Properties();
// 健壮性判断,如果没有这个目录就创建
if (!dir.exists())
dir.mkdir();
while ((len = fis.read(buf)) != -1) {
fos = new FileOutputStream(new File(dir, (count++) + ".part"));
// 开始写数据啦
fos.write(buf, 0, len);
fos.close();
}
// 将被切割文件的信息保存到prop集合中
prop.setProperty("partcount", count + "");
prop.setProperty("filename", file.getName());
fos = new FileOutputStream(new File(dir, count + ".properties"));
// 将prop集合中的数据存储到文件中来
prop.store(fos, "save file info");
fos.close();
fis.close();
}
// 合并============================================
private static void mergeFile(File dir) throws IOException {
// 合并文件首先到获取目录下的配置文件
File[] files = dir.listFiles(new SuffixFilter(".properties"));
if (files.length != 1)
throw new RuntimeException(dir + ",该目录下没有properties扩展名文件或不唯一");
// 记录配置文件对象
File confile = files[0];
// 获取该文件中的信息
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(confile);
prop.load(fis);
String filename = prop.getProperty("filename");
int count = Integer.parseInt(prop.getProperty("partcount"));
// 获取该目录下的所有碎片文件
File[] partFiles = dir.listFiles(new SuffixFilter(".part"));
if (partFiles.length != (count - 1)) {
throw new RuntimeException("碎片文件不符合要求");
}
// 将碎片文件和流对象关联,并存储到集合中
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for (int x = 0; x < partFiles.length; x++) {
al.add(new FileInputStream(partFiles[x]));
}
// 将多个流合并成一个序列流
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream(new File(dir, filename));
byte[] buf = new byte[1024];
int len = 0;
while ((len = sis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
sis.close();
}
/*
* 序列化和反序列化 ObjectOutputStream ObjectInputStream
* 序列化的过程就是讲对象的生命周期延长了,有些不想经常new的对象可以通过序列化将对象从 堆内存存储到硬盘中来。
* 存储在银盘上的文件一般后缀名用object表示。 文件不可以用txt解析,因为不是给用户看的,只是一个存储对象信息的数据文件。
* 序列化的对象要实现Serializable接口,Serializable就是一个标记接口,通常要设置一个国定有一个ID。 就这。
*/
}
// 文件过滤器=========================
class SuffixFilter implements FilenameFilter {
private String suffix;
public SuffixFilter(String suffix) {
super();
this.suffix = suffix;
}
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}
}
------- <a target="blank">android培训</a>、<a target="blank">java培训</a>、期待与您交流! -------