黑马程序员-探究字节流四(应用文件切割合并)

------- <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>、期待与您交流! -------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值