24-IO流-54-IO流(文件切割合并+配置文件)

/*
 * 前两个视频的弊端:在切割文件时候,不清楚切割成多少碎片文件,在合并文件时候,不清楚合并出来的是txt还是mp3还是别的
 * 
 * 解决办法:在切割时候,用配置文件记录源文件信息
 */


package demo;

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 Demo {

	private static final int SIZE = 1048576;

	public static void main(String[] args) throws IOException {

		File file = new File("D:\\Java-Eclipse-PersonalFile\\vedio24.IO.54\\0.mp3");
		splitFileDemo(file);
		File dir = new File("D:\\Java-Eclipse-PersonalFile\\vedio24.IO.54");
		mergeFileDemo(dir);
	}

	public static void splitFileDemo(File file) throws IOException {

		FileInputStream fis = new FileInputStream(file);
		
		byte[] buf = new byte[SIZE];
		
		int len = 0;
		
		int count = 1;
		
//切割文件时,必须记录注源文件(被切割文件的名称),以及记录切割成多少个碎片文件,目的是方便进行文件合并
//用键值对方式记录信息,且为了防止文件丢失,将其存于硬盘上,就用到了Properties,配置文件
		
		Properties prop = new Properties();
		
		FileOutputStream fos = null;
		
		File dir = new File("D:\\Java-Eclipse-PersonalFile\\vedio24.IO.54");
		
		if(!dir.exists())
			dir.mkdirs();
		
		while((len = fis.read(buf))!=-1){
			
			fos = new FileOutputStream (new File(dir,(count++) + ".part"));
/*
 * 【注意】count初值为1,while循环第一次,生成1.part,此时count=1+1=2;while循环第二次,生成2.part,此时count=2+1=3;
 * 以此类推,所以count=碎片文件数量+1,这就是为什么mergeFileDemo里面健壮性判断会出现if(partFiles.length != (count-1))
 */
			
			fos.write(buf,0,len);
			fos.close();
			
		}
		//将被切割的文件信息存储到prop集合中
		prop.setProperty("partcount", count+"");//partcount是键,对应的值是count+"",即碎片文件有count个
		
		prop.setProperty("filename", file.getName());//存储被切割的文件名(file是该函数传进来的参数)
		
		fos = new FileOutputStream(new File(dir,count + ".properties"));//配置文件是count.properties
		//将prop集合中的数据存储到文件中
		prop.store(fos, "save file info");
		
		fos.close();
		fis.close();
		
	}

	public static void mergeFileDemo(File dir) throws IOException {
		
//========================================================================================================
//【一】在合并文件之前,应该首先获取配置文件信息,如果有多个配置文件,那么需要过滤器;如果配置文件不存在,直接不用合并
		
		File[] files = dir.listFiles(new SuffixFilter(".properties"));
		//用listFiles()方法列举出dir中的文件,用过滤器suffixFilter过滤,拿到想要的配置文件
		
		/**
		 * 健壮性判断,如果没有配置文件,说明数组file为0(不等于1),如果不止一个配置文件,说明数组file内元素个数大于1
		 */
		
		if(files.length != 1)
			throw new RuntimeException(dir + "目录下没有扩展名为properties的文件或者符合条件的文件不唯一");
		//获取配置文件
		File configfile = files[0];
		
//=======================================================================================================	
//【二】获取配置信息

		//用读取流关联配置文件
		FileInputStream fis = new FileInputStream(configfile);
		
		//将配置文件中的信息读取到集合中
		Properties prop = new Properties();
		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("碎片个数不对,应该是"+count+"个");

//======================================================================================================
//【四】将碎片文件和流对象关联并存储到集合中
		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);

//=======================================================================================================
//【六】读取动作
	
		byte[] buf = new byte[1024];
		
		int len =0;
		
		FileOutputStream fos = new FileOutputStream(new File(dir,filename));
		
		while((len=sis.read(buf))!=-1){
			
			fos.write(buf,0,len);
			
		}
		
		fos.close();
		sis.close();
		
	}

}

================================分割线===================================

package demo;

import java.io.File;
import java.io.FilenameFilter;

public class SuffixFilter implements FilenameFilter {

	private String suffix;
	
	public SuffixFilter(String suffix) {//由用戶指定过滤文件的后缀名
		super();
		this.suffix = suffix;
	}

	@Override
	public boolean accept(File dir, String name) {

		return name.endsWith(suffix);
	}

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值