java15 IO装饰设计模式

简介:

复制代码
IO装饰设计模式:(IO中使用了装饰设计模式)
节点流可以直接从源读取数据,处理流就是对节点流的包装,这就是装饰,装饰就是对原有的流的性能的提升。比如买的车,马力不够,就进行装饰,使其马力增大。
装饰模式:
扩音器对声音进行了扩大。

类与类之间的关系(6种): 1、依赖:一个对象是形参或者局部变量,只有调用方法的时候才会依赖这个类。
2、关联:一个对象是属性。关联分为:
  聚合:是属性 整体与部分关系, 不一致的生命周期, 人与手
  组合:是属性 整体与部分关系, 一致的生命周期,  人与大脑
3、继承:父子类关系。
4、实现: 接口与实现类关系

public class Voice {
    private int voice =10;
    public Voice() {
        // TODO Auto-generated constructor stub
    }
    public int getVoice() {
        return voice;
    }
    public void setVoice(int voice) {
        this.voice = voice;
    }
    
    public void say(){
        System.out.println(voice);
    }
    
}



/**
 * 扩音器
 * 类与类之间的关系:
 * 1、依赖:一个对象是形参或者局部变量,只有调用方法的时候才会依赖这个类。
 * 2、关联:一个对象是属性。关联分为:
 *         聚合:是属性 整体与部分关系, 不一致的生命周期, 人与手
 *      组合:是属性 整体与部分关系, 一致的生命周期,  人与大脑
 * 3、继承:父子类关系。
 * 4、实现: 接口与实现类关系。
 */
public class Amplifier {
    private Voice voice;
    public Amplifier() {
    }
    public Amplifier(Voice voice) {
        super();
        this.voice = voice;
    }
    public void say(){
        System.out.println(voice.getVoice()*1000);
    }
}


public class App {
    public static void main(String[] args) {
        Voice v =new Voice();
        v.say();
        Amplifier am =new Amplifier(v);
        am.say();
    }
}




4.不能父目录拷贝到子目录中。
if(dest.getAbsolutePath().contains(src.getAbsolutePath())){
    System.out.println("父目录不能拷贝到子目录中");
    return;
}




/**
 * 文件的分割思路
 * 1、分割的块数 size   n块
 * 2、每一块的大小 blockSize
 *   最后:总的文件大小 -(n-1)*blockSize
 */
public class RndDemo01 {
    public static void main(String[] args) throws IOException {
        RandomAccessFile rnd =new RandomAccessFile(new File("E:/xp/test/a.txt"),"r");
        rnd.seek(30);//跳过30字节再开始。一个数字是4个字节
        //定义缓冲大小
        byte[] flush =new byte[10];
        //接收长度
        int len =0;         
        while(-1!=(len=rnd.read(flush))){
            if(len>=20){
                System.out.println(new String(flush,0,20));
                break;
            }else{
                System.out.println(new String(flush,0,len));
            }
        }
        FileUtil.close(rnd);
    }
}


文件的分割与合并:

public class SplitFile {
    //原始文件的路径
    private String filePath;
    //原始文件名
    private String fileName;
    //原始文件大小
    private long length;
    //根据每块的大小,确定分多少块
    private int size;
    //每块的大小
    private long blockSize;
    //分割后的存放目录
    private String destBlockPath;
    //每块的名称
    private List<String> blockPath;
    
    public SplitFile(){
        blockPath = new ArrayList<String>();
    }
    public SplitFile(String filePath,String destBlockPath){
        this(filePath,destBlockPath,1024);        
    }
    public SplitFile(String filePath,String destBlockPath,long blockSize){//方法里面一个个调用另一个方法,这是面向过程的思路。
        this();
        this.filePath= filePath;
        this.destBlockPath =destBlockPath;
        this.blockSize=blockSize;
        init();
    }
    
    /**
     * 初始化操作 计算 块数、确定文件名
     */
    public void init(){
        File src =null;
        //健壮性
        if(null==filePath ||!(((src=new File(filePath)).exists()))){
            return;
        }
        if(src.isDirectory()){
            return ;
        }
        //文件名
        this.fileName =src.getName();
        
        //计算块数 实际大小 与每块大小
        this.length = src.length();
        //修正 每块大小
        if(this.blockSize>length){
            this.blockSize =length;
        }
        //确定块数        
        size= (int)(Math.ceil(length*1.0/this.blockSize));
        //确定文件的路径
        initPathName();
    }
    
    private void initPathName(){
        for(int i=0;i<size;i++){
            this.blockPath.add(destBlockPath+"/"+this.fileName+".part"+i);
        }
    }
    
    /**
     * 文件的分割
     * 0)、第几块
     * 1、起始位置
     * 2、实际大小
     * @param destPath 分割文件存放目录
     */
    public void split(){    
        long beginPos =0;  //起始点
        long actualBlockSize =blockSize; //实际大小        
        //计算所有块的大小、位置、索引
        for(int i=0;i<size;i++){
            if(i==size-1){ //最后一块
                actualBlockSize =this.length-beginPos;
            }            
            spiltDetail(i,beginPos,actualBlockSize);
            beginPos+=actualBlockSize; //本次的终点,下一次的起点
        }
    }
    /**
     * 文件的分割 输入 输出
     * 文件拷贝
     * @param idx 第几块
     * @param beginPos 起始点
     * @param actualBlockSize 实际大小
     */
    private void spiltDetail(int idx,long beginPos,long actualBlockSize){
        //1、创建源
        File src = new File(this.filePath);  //源文件
        File dest = new File(this.blockPath.get(idx)); //目标文件
        //2、选择流
        RandomAccessFile raf = null;  //输入流,随机访问流。
        BufferedOutputStream bos=null; //输出流
        try {
            raf=new RandomAccessFile(src,"r");
            bos =new BufferedOutputStream(new FileOutputStream(dest));
            //读取文件,定位到起始位置。
            raf.seek(beginPos);
            //缓冲区
            byte[] flush = new byte[1024];
            //接收长度
            int len =0;
            while(-1!=(len=raf.read(flush))){                
                if(actualBlockSize-len>=0){ //查看是否足够
                    //写出
                    bos.write(flush, 0, len);
                    actualBlockSize-=len; //剩余量
                }else{ //写出最后一次的剩余量
                    bos.write(flush, 0, (int)actualBlockSize);
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            FileUtil.close(bos,raf);
        }
    }
    /**
     * 文件的合并
     */
    public void merge(String destPath){
        //创建源
        File dest =new File(destPath);
        //选择流
        BufferedOutputStream bos=null; //输出流
        SequenceInputStream sis =null ;//输入流
        //创建一个容器
        Vector<InputStream> vi = new Vector<InputStream>();        
        try {
            for (int i = 0; i < this.blockPath.size(); i++) {
                vi.add(new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i)))));//把每块文件的流搞成一个集合。
            }    
            bos =new BufferedOutputStream(new FileOutputStream(dest,true)); //追加
            sis=new SequenceInputStream(vi.elements());    //java.io.SequenceInputStream.SequenceInputStream(Enumeration<? extends InputStream> e)
        //public Enumeration<E> elements() 
                
            //缓冲区
            byte[] flush = new byte[1024];
            //接收长度
            int len =0;
            while(-1!=(len=sis.read(flush))){//读到程序里面来,所以是输入流。
                bos.write(flush, 0, len);//输出到目的地文件,所以是输出流。
            }
            bos.flush();
            FileUtil.close(sis);
        } catch (Exception e) {
        }finally{
            FileUtil.close(bos);
        }        
        
    }
    /**
     * 文件的合并
     */
    public void merge1(String destPath){
        //创建源
        File dest =new File(destPath);
        //选择流
        BufferedOutputStream bos=null; //输出流
        try {
            bos =new BufferedOutputStream(new FileOutputStream(dest,true)); //追加
            BufferedInputStream bis = null;
            for (int i = 0; i < this.blockPath.size(); i++) {
                bis = new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i))));
                //缓冲区
                byte[] flush = new byte[1024];
                //接收长度
                int len =0;
                while(-1!=(len=bis.read(flush))){
                    bos.write(flush, 0, len);
                }
                bos.flush();
                FileUtil.close(bis);
            }
        } catch (Exception e) {
        }finally{
            FileUtil.close(bos);
        }        
    }

    public static void main(String[] args) {
        SplitFile split = new SplitFile("E:/xp/20130502/test/学员设置(20130502).xls","E:/xp/20130502",51);
        System.out.println(split.size);
        split.split();
        split.merge("E:/xp/20130502/test1.xls");
    }
}



IO总结:
IO操作步骤:4步。创建源,选择流,操作,
如图
操作:递归打印,文件拷贝,关闭流的方法,文件的分割与合并。
复制代码

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/4833626.html,如需转载请自行联系原作者

相关文章
|
12天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
16天前
|
Java
java 中 IO 流
Java中的IO流是用于处理输入输出操作的机制,主要包括字节流和字符流两大类。字节流以8位字节为单位处理数据,如FileInputStream和FileOutputStream;字符流以16位Unicode字符为单位,如FileReader和FileWriter。这些流提供了读写文件、网络传输等基本功能。
38 9
|
23天前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
29 4
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
86 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
49 0
[Java]23种设计模式
|
27天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
2月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
39 1
|
2月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
95 1
|
2月前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
61 0