当前位置: 首页 > news >正文

Java的IO操作(四) - SequenceInputStream类,实例:一个文件分割、合并工具

SequenceInputStream可以看做是多个InputStream对象的有序集合。当一个InputStream对象的数据读取完后,它会自动取出下一个InputStream对象进行读取,直到所有的InputStream对象都读取完为止。

利用这个特点,我们来编写一个文件分割、合并工具。


使用说明:

SequenceDemo [Option] [filePath] [number]

Option:

-c : 表示要合并文件

-s : 表示要分割文件

filePath:

指定一个文件路径

number:

指定单个文件大小或文件数量

如:

 

java cls.SequeceDemo -s F:\QQ.exe 102400

表示将QQ.exe分割成多个文件大小为102400字节的小文件。

 

 

java cls.SequeceDemo -m F:\QQ.exe 13

表示将已经被分割好的13个QQ.exe文件合并成一个整文件。

 


注意,构造SequenceOutputStream对象时需要一个Enumeration对象的引用做为参数。Enumeration是一个接口,我们必须实现这个接口中的hasMoreElements()方法和nextElement()方法。

完整代码:

 

package cls;

import java.io.*;
import java.util.*;

public class SequenceStreamDemo
{
    public static void main(String[] args) throws Exception
    {
        switch(args[0].charAt(1))
        {
            case 's': // 分割文件
            {
                SequenceStreamDemo.seperate(args[1],Long.parseLong(args[2]));
                break;
            }
            case 'm': // 合并文件
            {
                SequenceStreamDemo.merge(args[1],Integer.parseInt(args[2]));
                break;
            }
            default: // 参数输入错误
            {
                System.out.println("非法参数");
                break;
            }
        }
    }
    
    /* 合并文件
    * fileName : 文件名
    * amount : 要合并的小文件的数量
    **/
    public static void merge(String fileName,int amount) throws Exception
    {
        // 创建合并后的文件
        File file = new File(fileName);
        FileOutputStream fis = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fis);
        
        // 将多个小文件对象保存在List中
        List<InputStream> list = new ArrayList<InputStream>();
        for(int i = 0 ; i < amount ; ++i)
        {
            File f = new File(fileName + "_" + i);
            list.add(new FileInputStream(f));
        }
        
        final Iterator<InputStream> it = list.iterator();
        
        // 构建Enumeration对象
        Enumeration<InputStream> em = new Enumeration<InputStream>()
        {
            public boolean hasMoreElements()
            {
                return it.hasNext();
            }
            public InputStream nextElement()
            {
                return it.next();
            }
        };
        
        // 使用SequenceInputStream合并文件
        BufferedInputStream bis = new BufferedInputStream(new SequenceInputStream(em),8192);
        int data;
        
        while((data = bis.read()) != -1)
        {
            bos.write(data);
        }
        
        bis.close();
        bos.flush();
        bos.close();
        
        System.out.println("合并完成");
    }
    /* 分割文件
    * fileName : 文件名
    * size : 单个文件的大小
    **/
    public static void seperate(String fileName,long size) throws Exception
    {
        File file = new File(fileName);
        long number;
        
        // 计算分割后的文件数量
        if(0 == file.length() % size)
        {
            number = file.length() / size;
        }
        else
        {
            number = file.length() / size + 1;
        }
        
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        
        // 开始分割
        byte[] buf = new byte[1];
        for(int i = 0 ; i < number ; ++i)
        {
            FileOutputStream fos = new FileOutputStream(new File(fileName + "_" + i));
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            
            long curSize = 0L;
            while(bis.read(buf) != -1)
            {
                bos.write(buf);
                
                curSize++;
                if(curSize == size) // 已经分割成了一个小文件
                {
                    bos.flush();
                    bos.close();
                    break;
                }
            }
            if(curSize < size) // 打包剩下的数据
            {
                bos.flush();
                bos.close();
                break;
            }
            
        }
        
        System.out.println("分割完成");
    }
}


 



 

相关文章:

  • eclipse中默认js编辑器非常慢,尤其在拷贝粘贴代码时的解决方法
  • 禽流感注意事项
  • setTimeout,setInterval的使用小结
  • C# WF中关闭按钮的状态判定,根据用户选择执行不同的方法
  • iPhone上画圆角矩形的方法
  • CPP 插入排序
  • Android 获取网页内容
  • 系统子模块_短信命令语法设计
  • 高效能人士的七个习惯(部分)
  • 以XML为中间文档格式的Excel电子表格向SVG图转换
  • Visifire for Windows 8 v2.1.1.0 发布
  • JNDI 学习(转)
  • 不可不知的移动色彩设计新趋势
  • Nosql入门知识(转)
  • linux 下oracle提示:the account is locked
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • AHK 中 = 和 == 等比较运算符的用法
  • Android系统模拟器绘制实现概述
  • Javascript基础之Array数组API
  • Java基本数据类型之Number
  • JS 面试题总结
  • spring boot 整合mybatis 无法输出sql的问题
  • webpack+react项目初体验——记录我的webpack环境配置
  • 笨办法学C 练习34:动态数组
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 数据可视化之 Sankey 桑基图的实现
  • 微信开放平台全网发布【失败】的几点排查方法
  • 为什么要用IPython/Jupyter?
  • 学习ES6 变量的解构赋值
  • zabbix3.2监控linux磁盘IO
  • 我们雇佣了一只大猴子...
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • #ifdef 的技巧用法
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (TOJ2804)Even? Odd?
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (六)激光线扫描-三维重建
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)EOS中账户、钱包和密钥的关系
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • @DataRedisTest测试redis从未如此丝滑
  • @Data注解的作用
  • [16/N]论得趣
  • [android] 练习PopupWindow实现对话框
  • [AX]AX2012 SSRS报表Drill through action
  • [BUUCTF]-Reverse:reverse3解析
  • [C++从入门到精通] 14.虚函数、纯虚函数和虚析构(virtual)
  • [Java] 什么是IoC?什么是DI?它们的区别是什么?
  • [LeetCode] 197. 上升的温度
  • [leetcode]56. Merge Intervals归并区间
  • [LeetCode]—Permutations II 求全排列(有重复值)
  • [Linux]----文件操作(复习C语言+文件描述符)