java文件拆分与合并

拆分和合并需要先导入一些java包

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

主程序

	public static void main(String[] args) {
	File f = new File("D:/Java_file/2014.xlsx");
	tools.split(f);

	File[] fs = f.listFiles();
	File newfile = new File("DD:/Java_file/newfile");
	tools.merge(fs,newfile);
	

split和merge均为tools静态方法

拆分文件

读数据的流不结束,直到读完整个文档,写数据的流写完一个分割文件就关闭,下一个分割文件再打开一个新的。

	public static void split(File f){		//传入文件对象
	byte[] data = new byte[(int)f.length()];//构造一个对象数组
	try(FileInputStream fis = new FileInputStream(f)){
		fis.read(data);						//将数据读取到data数组中
		}
	catch(FileNotFoundException e) {
			e.printStackTrace();
		}
	catch(IOException e){
			e.printStackTrace();
		}

	int len = 1024*10; 						//将文件以10k单位拆分
	int n = (int)f.length()/len;			//能拆成多少个单位
	File[] fs = new File[n+1];				//定义n+1个文件数据

	for(int i =0;i<n+1;i++){				
	int start = i*len;						//初始位置
	int end = (i+1)*len;					//结束位置
	fs[i] = new file(f+"-"+i);				//文件存放
	if(i<n){	//文件为10k单位时
		byte[] b = Arrays.copyOfRange(data,start,end);
		//将指定数组的指定范围复制到一个新数组,返回值是数组,前闭后开
		try(FileOutputStream fos = new FileOutputStream(fs[i])){
			fos.write(b);					//把b内容写入到指定文件
			}
		catch(FileNotFoundException e) {
				e.printStackTrace();
			}
		catch(IOException e){
				e.printStackTrace();
			}
	}

	else{	//最后一个文件
		start = i*len;
		end = (int)f.length();			//结束位置为文件结尾
		byte[] b = Arrays.copyOfRange(data,start,end);
		try(FileOutputStream fos = new FileOutputStream(fs[i])){
			fos.write(b);
			}
		catch(FileNotFoundException e) {
				e.printStackTrace();
			}
		catch(IOException e){
				e.printStackTrace();
			}
	}

	System.out.println("输出子文件夹:" + fs[i].getAbsolutePath() 
					+ "  其长度为: " + fs[i].length()); 
					//getAbsolutePath方法返回绝对路径
	}
	}

合并文件

写数据的流不结束,直到写完整个文档,读数据的流读完一个分割文件就关闭,下一个分割文件再打开一个新的。

	public static void merge(File[] fs,File file){
	int len = 0;				//文件长度
	for(File f:fs){
		len +=(int)f.length();
	}
	
	byte[] data = new byte[len];//构造一个最大长度的文件
	int len1 = 0;				//目标数组的下标位置
	for(File f:fs){
		byte[] bi = new byte[(int)f.length()];	//构造一个长度于file相同的数组
		try(FileInputStream fis = new FileInputStream(f)){
			fis.read(bi);					//将读取的数据保存在bi中
			System.out.println(bi.length);	//输出每个文件的长度
		}
		catch(FileNotFoundException e) {
				e.printStackTrace();
			}
		catch(IOException e){
				e.printStackTrace();
			}
		Ststem.arraycopy(bi,0,data,len1,(int)f.length());
		//将bi中的指定数据复制到data中,bi是数据源,0是复制起始位置,data是目标数据,len1是目标数据的插入位置,f.length是数据长度
		len1 += (int)f.length();			//更新插入位置

		try(FileOutputStream fos = new FileOutputStream(file)){
			fos.write(data);				//将数据写入目标文件中
		}
		catch(FileNotFoundException e) {
				e.printStackTrace();
			}
		catch(IOException e){
				e.printStackTrace();
			}
	}
	}

关于流的关闭
有两种常用关闭方法:

第一种是使用try-with-resources(声明了一个或多个资源的try语句)的方式, 本文代码就采用的此方式.
所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。
但只支持JDK7以上的版本

	try(FileOutputStream fos = new FileOutputStream(file)){
			fos.write(data);	
		}
		
	try(FileInputStream fis = new FileInputStream(f)){
			fis.read(bi);					
		}
		//不需要手动关闭

第二种是标准的关闭流的方法

  1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
  2. 在finally关闭之前,要先判断该引用是否为空
  3. 关闭的时候,需要再一次进行try catch处理
	FileInputStream fis = null;
	try {
            fis = new FileInputStream(f);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {  // 在finally 里关闭流
            if (null != fis)
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        //流一定要在try的外面声明!

两种关闭流的方式功能是相同的, 第一种只支持JDK7以上的版本, 而第二种在任何时候都有效果,但也更为繁琐

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值