java IO 输入输出(十一)

来源:互联网 发布:网络通信英文 编辑:程序博客网 时间:2024/04/28 12:33

十一、文件的分割与合并

    实现文件分割与合并的关键技术点如下:
    1、分割文件时,指定小文件的长度(字节数),根据File的length方法获得大文件的长度,以确定目标小文件的数目。用文件输入流顺序地读取大文件的数据,将数据分流到每个小文件的输出流中
    2、合并文件时,读取每个小文件的输入流,将所有内容按顺序写如到目标大文件的输出流中
   
实例演示

 

package book.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * 文件分割合并器,将大文件分割成若干小文件,将多个小文件合并到一个大文件
 * 
@author joe
 *
 
*/


public class FileDivisionUniter {
    
    
public static final String SUFFIX = ".pp";    //分割后的文件名后缀
    
    
/**
     * 分割文件
     * 
@param fileName    待分割的文件名
     * 
@param size    小文件的大小,单位字节
     * 
@return    分割成的小文件的文件名
     * 
@throws Exception    分割过程中可能抛出的异常
     
*/

    
public static String[] divide(String fileName, long size) throws Exception{
        File inFile 
= new File(fileName);
        
if (!inFile.exists()) {
            
throw new Exception("指定文件不存在");
        }

        
//获得被分割文件父文件,将来被分割成的小文件便存在这个目录下
        File parentFile = inFile.getParentFile();
        
        
//获得文件的大小
        long fileLength = inFile.length();
        
if (size <= 0{
            size 
= fileLength / 2;
        }

        
//取得被分割后的小文件的数目
        int num = (fileLength % size != 0? (int)(fileLength / size + 1) : (int)(fileLength / size);
        
//存放被分割后的小文件名
        String[] outFileNames = new String[num];
        
//输入文件流,即被分割的文件
        FileInputStream in = new FileInputStream(inFile);
        
        
//读输入文件的开始和结束下标
        long inBeginIndex = 0;
        
long inEndIndex = 0;
        
        
//根据要分割的数目输出文件
        for (int outFileIndex = 0; outFileIndex < num; outFileIndex++{
            
//对于前num - 1个小文件,大小都为指定的size
            File outFile = new File(parentFile, inFile.getName() + outFileIndex + SUFFIX);
            
//构建小文件的输出流
            FileOutputStream out = new FileOutputStream(outFile);
            
//将结束下标后移size
            inEndIndex = inEndIndex + size;
            inEndIndex 
= (inEndIndex > fileLength) ? fileLength : inEndIndex;
            
//从输入流中读取字节存储到输出流中
            for (; inBeginIndex < inEndIndex; inBeginIndex++{
                out.write(in.read());
            }

            out.close();
            outFileNames[outFileIndex] 
= outFile.getAbsolutePath();
        }

        in.close();
        
return outFileNames;
    }

    
    
/**
     * 合并文件
     * 
@param fileNames    待合并的文件名,是一个数组
     * 
@param TargetFileName    目标文件名
     * 
@return    目标文件的全路径
     * 
@throws Exception    合并过程中可能出现的异常
     
*/

    
public static String unite(String[] fileNames, String TargetFileName) throws Exception {
        File inFile 
= null;
        
//构建文件输出流
        File outFile = new File(TargetFileName);
        FileOutputStream out 
= new FileOutputStream(outFile);
        
        
for (int i = 0; i < fileNames.length; i++{
            
//打开文件输入流
            inFile = new File(fileNames[i]);
            FileInputStream in 
= new FileInputStream(inFile);
            
//从输入流中读取数据,并写入到文件输出流中
            int c;
            
while((c = in.read()) != -1{
                out.write(c);
            }

            in.close();
        }

        out.close();
        
        
return outFile.getAbsolutePath();
    }

    
    
public static void main(String[] args) throws Exception {
        
//分割文件
        String fileName = "d:/work/temp/temp.xls";
        
long size = 2000;
        String[] fileNames 
= FileDivisionUniter.divide(fileName, size);
        System.out.println(
"分割文件" + fileName + "结果:");
        
for (int i = 0; i < fileNames.length; i++{
            System.out.println(fileNames[i]);
        }

        
//合并文件
        String newFileName = "d:/work/temp/newTemp.xls";
        System.out.println(
"合并文件结果:" + FileDivisionUniter.unite(fileNames, newFileName));
    }


}

 输出结果:
分割文件d:/work/temp/temp.xls结果:
d:/work/temp/temp.xls0.pp
d:/work/temp/temp.xls1.pp
d:/work/temp/temp.xls2.pp
d:/work/temp/temp.xls3.pp
d:/work/temp/temp.xls4.pp
d:/work/temp/temp.xls5.pp
d:/work/temp/temp.xls6.pp
合并文件结果:d:/work/temp/newTemp.xls

原创粉丝点击