精华内容
下载资源
问答
  • 复制的四种方式
    千次阅读
    2020-09-09 20:25:34

    java对象属性复制的几种方式
    1.使用java反射机制,获取对象的属性和get、set方法进行复制;

    2.使用spring-beans5.0.8包中的BeanUtils类

    import org.springframework.beans.BeanUtils;

    SourceObject sourceObject = new SourceObject();
    TargetObject targetObject = new TargetObject();
    BeanUtils.copyProperties(sourceObject, targetObject);

    3.使用cglib3.2.8包中的net.sf.cglib.beans.BeanCopier类

    import net.sf.cglib.beans.BeanCopier;
    import net.sf.cglib.core.Converter;
    SourceObject sourceObject = new SourceObject();
    TargetObject targetObject = new TargetObject();
    BeanCopier beanCopier = BeanCopier.create(SourceObject.class, TargetObject.class, true);–第三个参数表示是否使用转换器,false表示不使用,true表示使用
    Converter converter = new CopyConverter();–自定义转换器
    beanCopier.copy(sourceObject, targetObject, converter);

    转换器(当源对象属性类型与目标对象属性类型不一致时,使用转换器):
    import net.sf.cglib.core.Converter;
    import org.apache.commons.lang3.StringUtils;

    import java.math.BigDecimal;
    import java.util.Date;

    /**

    • Created by asus on 2019/7/12.
      */
      public class CopyConverter implements Converter {

      @Override
      public Object convert(Object value, Class target, Object context) {
      {
      String s = value.toString();
      if (target.equals(int.class) || target.equals(Integer.class)) {
      return Integer.parseInt(s);
      }
      if (target.equals(long.class) || target.equals(Long.class)) {
      return Long.parseLong(s);
      }
      if (target.equals(float.class) || target.equals(Float.class)) {
      return Float.parseFloat(s);
      }
      if (target.equals(double.class) || target.equals(Double.class)) {
      return Double.parseDouble(s);
      }
      if(target.equals(Date.class)){
      while(s.indexOf("-")>0){
      s = s.replace("-", “/”);
      }
      return new Date(s);
      }
      if(target.equals(BigDecimal.class)){
      if(!StringUtils.isEmpty(s)&&!s.equals(“NaN”)){
      return new BigDecimal(s);
      }
      }
      return value ;

       }
      

      }
      }

    4.使用spring-core5.0.8包中的org.springframework.cglib.beans.BeanCopier类(用法与第三种一样)

    import org.springframework.cglib.beans.BeanCopier;
    import org.springframework.cglib.core.Converter;
    SourceObject sourceObject = new SourceObject();
    TargetObject targetObject = new TargetObject();
    Converter converter = new SpringCopyConverter();
    BeanCopier beanCopier = BeanCopier.create(SourceObject.class, TargetObject.class, true);
    beanCopier.copy(sourceObject, targetObject, converter);

    经过循环复制测试(源对象与目标对象各160个属性):
    在这里插入图片描述
    补充:

    第一种:Java反射通过判断属性类型,常用类型的属性值都能复制,但是不优化的前提下效率最慢;

    第二种:属性类型不同时无法复制,且效率相对较慢;

    第三种:耗时最少,不使用转换器时,属性类型不同时无法复制,使用转换器后,耗时会相对变长;

    第四种:与第三种相似,但是耗时相对较长;

    大家在日常的java开发中,经常会使用到对象之间属性的赋值操作,如果两个对象之间复制的属性不多的时候,我们一般都会使用java提供的get、set方法进行复制。但是碰到对象的属性数量特别多的时候(业务代码对象动辄几十上百个属性),属性复制手工输入上百个get、set将会特别耗时耗力。
      如何使用一句简单的代码直接复制上百个属性,这里介绍几种常用的方法,以及本人在实际项目中碰到的一个坑。

    使用org.apache.commons.beanutils.BeanUtils.copyProperties(Object
    dest, Object orig); dest目标对象,orig源对象。(这个方法比较坑,耗时严重,之后介绍)
    使用org.springframework.beans.BeanUtils.copyProperties(Object source,
    Object target); source源对象,target对象。(注意和apache的是反过来的) 1.
    使用net.sf.cglib.beans.BeanCopier.copy(from, to, null);
    先定义BeanCopier beanCopier =BeanCopier.create(“要转换的类”, “转换后的类”, false);   再复制beanCopier.copy(from, to, null);
    org.springframework.cglib.beans.BeanCopier.copy(from, to, null);
    先定义BeanCopier beanCopier =BeanCopier.create(“要转换的类”, “转换后的类”, false);   再进行复制beanCopier.copy(from, to, null);

    本人做了简单的测试,如下:
      JAVA对象复制对比测试
      可以发现org.apache.commons.beanutils.BeanUtils.copyProperties在属性多的情况复制效率严重低下,本人曾使用这个方法也被坑惨了。
      推荐使用spring的beanUtils或者BeanCopier,使用简单方便,效率较高,上百行的属性复制一行搞定,轻松愉快。
      本人也是做了简单的测试,还有其他的坑估计还要进行进一步深入探索。

    转载:https://www.cnblogs.com/cyf18/articles/11178869.html
    转载: https://blog.csdn.net/xiaoyang226/article/details/81939912

    更多相关内容
  • Java对象的复制四种方式

    千次阅读 2019-03-16 08:57:56
    先介绍一下两不同的克隆方法,浅克隆(ShallowClone)和深克隆(DeepClone)。 在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用...

    1、概述
    在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能 会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。例如下面程序展示的情况:

    class Student {  
        private int number;  
    
        public int getNumber() {  
            return number;  
        }  
    
        public void setNumber(int number) {  
            this.number = number;  
        }  
    
    }  
    public class Test {   
        public static void main(String args[]) {  
            Student stu1 = new Student();  
            stu1.setNumber(12345);  
            Student stu2 = stu1;  
            stu1.setNumber(54321);  
            System.out.println("学生1:" + stu1.getNumber());  
            System.out.println("学生2:" + stu2.getNumber());  
        }  
    }

    结果:

    学生1:54321 
    学生2:54321

    为什么改变学生2的学号,学生1的学号也发生了变化呢? 
    原因出在(stu2 = stu1) 这一句。该语句的作用是将stu1的引用赋值给stu2, 
    这样,stu1和stu2指向内存堆中同一个对象。如图:

    è¿éå代ç ç

    那么,怎么能干干净净清清楚楚地复制一个对象呢。在 Java语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求有很多途径, 
    (1)将A对象的值分别通过set方法加入B对象中; 
    (2)通过重写java.lang.Object类中的方法clone(); 
    (3)通过org.apache.commons中的工具类BeanUtils和PropertyUtils进行对象复制; 
    (4)通过序列化实现对象的复制。

    2、将A对象的值分别通过set方法加入B对象中
    对属性逐个赋值,本实例为了演示简单就设置了一个属性:

    Student stu1 = new Student();  
    stu1.setNumber(12345);  
    Student stu2 = new Student();  
    stu2.setNumber(stu1.getNumber());

    我们发现,属性少对属性逐个赋值还挺方便,但是属性多时,就需要一直get、set了,非常麻烦。

    3、重写java.lang.Object类中的方法clone()
    先介绍一下两种不同的克隆方法,浅克隆(ShallowClone)和深克隆(DeepClone)。

    在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制,下面将对两者进行详细介绍。

    3.1 浅克隆
    一般步骤:

    被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法)

    覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。(native为本地方法)

    class Student implements Cloneable{  
        private int number;  
    
        public int getNumber() {  
            return number;  
        }  
    
        public void setNumber(int number) {  
            this.number = number;  
        }  
    
        @Override  
        public Object clone() {  
            Student stu = null;  
            try{  
                stu = (Student)super.clone();  
            }catch(CloneNotSupportedException e) {  
                e.printStackTrace();  
            }  
            return stu;  
        }  
    }  
    public class Test {  
        public static void main(String args[]) {  
            Student stu1 = new Student();  
            stu1.setNumber(12345);  
            Student stu2 = (Student)stu1.clone();  
    
            System.out.println("学生1:" + stu1.getNumber());  
            System.out.println("学生2:" + stu2.getNumber());  
    
            stu2.setNumber(54321);  
    
            System.out.println("学生1:" + stu1.getNumber());  
            System.out.println("学生2:" + stu2.getNumber());  
        }  
    }  

    结果: 
    学生1:12345 
    学生2:12345 
    学生1:12345 
    学生2:54321

    在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。

    简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。

     è¿éåå¾çæè¿°
    在Java语言中,通过覆盖Object类的clone()方法可以实现浅克隆。3.2 深克隆

    package abc;  
    
    class Address implements Cloneable {  
        private String add;  
    
        public String getAdd() {  
            return add;  
        }  
    
        public void setAdd(String add) {  
            this.add = add;  
        }  
    
        @Override  
        public Object clone() {  
            Address addr = null;  
            try{  
                addr = (Address)super.clone();  
            }catch(CloneNotSupportedException e) {  
                e.printStackTrace();  
            }  
            return addr;  
        }  
    }  
    
    class Student implements Cloneable{  
        private int number;  
    
        private Address addr;  
    
        public Address getAddr() {  
            return addr;  
        }  
    
        public void setAddr(Address addr) {  
            this.addr = addr;  
        }  
    
        public int getNumber() {  
            return number;  
        }  
    
        public void setNumber(int number) {  
            this.number = number;  
        }  
    
        @Override  
        public Object clone() {  
            Student stu = null;  
            try{  
                stu = (Student)super.clone();   //浅复制  
            }catch(CloneNotSupportedException e) {  
                e.printStackTrace();  
            }  
            stu.addr = (Address)addr.clone();   //深度复制  
            return stu;  
        }  
    }  
    public class Test {  
    
        public static void main(String args[]) {  
    
            Address addr = new Address();  
            addr.setAdd("杭州市");  
            Student stu1 = new Student();  
            stu1.setNumber(123);  
            stu1.setAddr(addr);  
    
            Student stu2 = (Student)stu1.clone();  
    
            System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
            System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
    
            addr.setAdd("西湖区");  
    
            System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
            System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
        }  
    }

    结果: 
    学生1:123,地址:杭州市 
    学生2:123,地址:杭州市 
    学生1:123,地址:西湖区 
    学生2:123,地址:西湖区

    怎么两个学生的地址都改变了?

    原因是浅复制只是复制了addr变量的引用,并没有真正的开辟另一块空间,将值复制后再将引用返回给新对象。

    为了达到真正的复制对象,而不是纯粹引用复制。我们需要将Address类可复制化,并且修改clone方法,完整代码如下:

    package abc;  
    
    class Address implements Cloneable {  
        private String add;  
    
        public String getAdd() {  
            return add;  
        }  
    
        public void setAdd(String add) {  
            this.add = add;  
        }  
    
        @Override  
        public Object clone() {  
            Address addr = null;  
            try{  
                addr = (Address)super.clone();  
            }catch(CloneNotSupportedException e) {  
                e.printStackTrace();  
            }  
            return addr;  
        }  
    }  
    
    class Student implements Cloneable{  
        private int number;  
    
        private Address addr;  
    
        public Address getAddr() {  
            return addr;  
        }  
    
        public void setAddr(Address addr) {  
            this.addr = addr;  
        }  
    
        public int getNumber() {  
            return number;  
        }  
    
        public void setNumber(int number) {  
            this.number = number;  
        }  
    
        @Override  
        public Object clone() {  
            Student stu = null;  
            try{  
                stu = (Student)super.clone();   //浅复制  
            }catch(CloneNotSupportedException e) {  
                e.printStackTrace();  
            }  
            stu.addr = (Address)addr.clone();   //深度复制  
            return stu;  
        }  
    }  
    public class Test {  
    
        public static void main(String args[]) {  
    
            Address addr = new Address();  
            addr.setAdd("杭州市");  
            Student stu1 = new Student();  
            stu1.setNumber(123);  
            stu1.setAddr(addr);  
    
            Student stu2 = (Student)stu1.clone();  
    
            System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
            System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
    
            addr.setAdd("西湖区");  
    
            System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
            System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
        }  
    }

    结果: 
    学生1:123,地址:杭州市 
    学生2:123,地址:杭州市 
    学生1:123,地址:西湖区 
    学生2:123,地址:杭州市

    在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

    简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。 
     è¿éåå¾çæè¿°
    在Java语言中,如果需要实现深克隆,可以通过覆盖Object类的clone()方法实现,也可以通过序列化(Serialization)等方式来实现。

    (如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。)

    4、工具类BeanUtils和PropertyUtils进行对象复制

    Student stu1 = new Student();  
    stu1.setNumber(12345);  
    Student stu2 = new Student(); 
    BeanUtils.copyProperties(stu2,stu1);

    这种写法无论多少种属性都只需要一行代码搞定,很方便吧!除BeanUtils外还有一个名为PropertyUtils的工具类,它也提供copyProperties()方法,作用与BeanUtils的同名方法十分相似,主要的区别在于BeanUtils提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而PropertyUtils不支持这个功能,但是速度会更快一些。在实际开发中,BeanUtils使用更普遍一点,犯错的风险更低一点。

    5、通过序列化实现对象的复制
    序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。

    要更多干货、技术猛料的孩子,快点拿起手机扫码关注我,我在这里等你哦~

                                                           

    展开全文
  • 文件越大,四种方式的比较效果越明显 输入:要复制的文件路径+文件名,该文件要复制的目标路径 输出:复制所耗时间(毫秒) 代码如下: import java.io.*; public class CopyFileDemo { public static...

    功能:

    读取一个文件的字节流,在另一个文件夹将字节output到硬盘

    文件越大,四种方式的比较效果越明显

    输入:要复制的文件路径+文件名,该文件要复制的目标路径

    输出:复制所耗时间(毫秒)

     

     

     

    代码如下:

    import java.io.*;
    
    public class CopyFileDemo {
        public static void main(String[] args) throws IOException {
            String filepath = "D:\\JAVA\\FileTest\\test.jpg";//要复制的图片
            String copypath = "D:\\JAVA\\FileTest\\CopyFiles";//复制文件的目标路径
    
            String filename = new File(filepath).getName();//根据文件名截取后缀名:filename.substring(filename.lastIndexOf("."))
            System.out.println("---------本次复制的文件大小为:"+new File(filepath).length()+"字节--------");
    
            copy1(filepath,copypath,filename.substring(filename.lastIndexOf(".")));
            copy2(filepath,copypath,filename.substring(filename.lastIndexOf(".")));
            copy3(filepath,copypath,filename.substring(filename.lastIndexOf(".")));
            copy4(filepath,copypath,filename.substring(filename.lastIndexOf(".")));
        }
        
        //方式1 每个字节循环遍历获取,效率低下
        public static void copy1(String filepath,String copypath,String fileType) throws IOException {
            //创建输入流 读取硬盘数据
            FileInputStream fis = new FileInputStream(filepath);
    
            //创建输出流 从内存写入硬盘
            FileOutputStream fos = new FileOutputStream(copypath+"\\copyBy单个字节"+fileType);
    
            long startTime = System.currentTimeMillis();
            int len;
            while ((len = fis.read()) != -1 ){
                fos.write(len);//遍历将每个字节写入新的文件
            }
            //释放资源,注意,释放资源必须要先释放写,再释放读
            fos.close();
            fis.close();
            System.out.println("按照每个字节完成复制,耗时"+(System.currentTimeMillis()-startTime)+"毫秒");
        }
    
        //方式2 使用缓冲数组byte[]遍历获取 效率高很多
        public static void copy2(String filepath,String copypath,String fileType) throws IOException {
            //创建输入流 读取硬盘数据
            FileInputStream fis = new FileInputStream(filepath);
    
            //创建输出流 从内存写入硬盘
            FileOutputStream fos = new FileOutputStream(copypath+"\\copyBy缓冲数组"+fileType);
    
            long startTime = System.currentTimeMillis();
            startTime = System.currentTimeMillis();
            int len;
            byte[] bytes = new byte[1024];//缓冲区大小为1024字节,也就是1K
            while ((len = fis.read(bytes)) != -1){
                fos.write(bytes,0,len);//如复制到文件大于1024字节,则每次写1024字节到缓冲数组 若小于1024字节,则直接全部写入缓冲数组
            }
            fos.close();
            fis.close();
            System.out.println("使用byte缓冲数组完成复制,耗时"+(System.currentTimeMillis()-startTime)+"毫秒");
        }
    
        //方式3 使用Buffered的缓冲流对每个字节循环遍历获取,效率比不使用Buffered要高许多
        public static void copy3(String filepath,String copypath,String fileType) throws IOException {
            //创建输入缓冲流 读取硬盘数据
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filepath));
    
            //创建输出缓冲流 从内存写入硬盘
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(copypath+"\\copyBy缓冲字节流"+fileType));
    
            long startTime = System.currentTimeMillis();
            int len;
            while ((len = bis.read()) != -1 ){
                bos.write(len);//遍历将每个字节写入新的文件
            }
            //释放资源,注意,释放资源必须要先释放写,再释放读
            bos.close();
            bis.close();
            System.out.println("缓冲字节流按照每个字节完成复制,耗时"+(System.currentTimeMillis()-startTime)+"毫秒");
        }
    
        //方式4 使用Buffered的缓冲流+缓冲数组byte[]遍历获取 效率最高
        public static void copy4(String filepath,String copypath,String fileType) throws IOException {
            //创建输入缓冲流 读取硬盘数据
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filepath));
    
            //创建输出缓冲流 从内存写入硬盘
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(copypath+"\\copyBy缓冲字节流和缓冲数组"+fileType));
    
            long startTime = System.currentTimeMillis();
            startTime = System.currentTimeMillis();
            int len;
            byte[] bytes = new byte[1024];//缓冲区大小为1024字节,也就是1K
            while ((len = bis.read(bytes)) != -1){
                bos.write(bytes,0,len);//如复制到文件大于1024字节,则每次写1024字节到缓冲数组 若小于1024字节,则直接全部写入缓冲数组
            }
            bos.close();
            bis.close();
            System.out.println("缓冲字节流使用byte缓冲数组完成复制,耗时"+(System.currentTimeMillis()-startTime)+"毫秒");
        }
    }

    输出结果截图如下:

    可以看出,就单个字节的复制而言,使用字节缓冲数组可以有效提高文件复制效率(比较第二行和第三行),而使用Buffer缓冲字节流也比基础的单个字节流复制要高许多(比较第二行和第四行)。但效率最高的是Buffer字节流缓冲和缓冲数组结合使用(第五行)。

     

    展开全文
  • js 复制文本的四种方式

    千次阅读 2018-06-16 05:06:00
    js 复制文本的四种方式 一、总结 一句话总结:js文本复制主流方法:document的execCommand方法     二、js 复制文本的四种方式 纯 转载复制,非原创 原地址:http://www.cnblogs.com/xhyu/p/5370111.html ...

    js 复制文本的四种方式

    一、总结

    一句话总结:js文本复制主流方法:document的execCommand方法

     

     

    二、js 复制文本的四种方式

    纯 转载复制,非原创

    原地址:http://www.cnblogs.com/xhyu/p/5370111.html

    目前copy主流有四种方式:ZeroClipboardClipboard.jsexecCommand,setData,再就是其他只支持IE的鸡肋法了不在此讨论。。

    概况:

    ZeroClipboard 就是常说的Flash法,通过加载一个Flash,让其访问系统剪贴板来绕过绝大多数系统的权限限制,然而体积稍微庞大些

    Clipboard.js 近几年使用较多,体积相对小,兼容性可以接受,使用还比较方便。

    execCommand 新兴势力,safari等主流正在努力兼容,是个好东西。

    setData 太老。。一般不太用,基本只适合IE

    兼容性:

    ZeroClipboard 兼容性最好,能全面兼容chrome/ FireFox/ IE/ 甚至Safari 这种“友好”的浏览器

    Clipboard.js和execCommand兼容性相似,兼容chrome/ FF/ IE>9/ Safari新版(不太懂Safari版本号如何算。。感觉15年以后的都可以)

    setData 仅IE

    体积:

    ZeroClipboard 插件较大,230KB

    Clipboard.js 较小,4KB

    execCommand是document方法,不用插件直接搞

    虽说体积有差,加载起来速度差不多的其实。。话说git好像就是用的ZeroClipboard

     

    Clipboard.js 实验经过:

    直接忽略胖胖的Flash法,,先盯上的Clipboard.js,用起来着实简单,先引用压缩版:

    <script src="dist/clipboard.min.js"></script>

    新建Clipboard对象(顺便:'.btn'给所有class="btn"的元素都加了监听,其他用法可查JS)

    复制代码
    var clipboard = new Clipboard('.btn');
    
    //可以自己加些处理
    clipboard.on('success', function(e) {
        console.info('Action:', e.action);
        console.info('Text:', e.text);
        console.info('Trigger:', e.trigger);
    
        e.clearSelection();
    });
    clipboard.on('error', function(e) {
        console.error('Action:', e.action);
        console.error('Trigger:', e.trigger);
    });
    复制代码

    HTML里这样就OK了

    <button class="btn" data-clipboard-target="#foo">

    使用清爽,测试通过,然而项目只有一个地方用到copy,为了他加个插件真是不优美。。于是终于找到了近期出现的execCommand()大法 (生在了好时代Orz)

     

    execCommand()大法:

    其实只需要选中要复制的内容,执行document.execCommand('copy', false, null)就好了。execCommand里可以跑很多例如paste等方法,第一个参数是方法名,第二个是是否展示默认ui,第三个是可选参数列表,对copy来说后两个都用不到。

    根据兼容不同,执行后可能的情况(涉及返回值):

    1.不支持execCommand:抛出异常 2.不支持copy方法:返回false 3.成功:true

    因此框架可以这样写:

    复制代码
    copy_target.focus();
    copy_target.select();
    try{
        if(document.execCommand('copy', false, null)){
            //success info
        } else{
            //fail info
        }
    } catch(err){
        //fail info
    }
    复制代码

    给用户的反馈用的jquery的tooltip,然后写成一个function就是如下:

    复制代码
    function copy(copytargetid,copybtnid){
        var cpt = document.getElementById(copytargetid);
        var cpb = document.getElementById(copybtnid);
        $(cpt).focus();
        $(cpt).select();
        try{
            if(document.execCommand('copy', false, null)){
                $(cpb).tooltip({title:"copied!", placement: "bottom", trigger: "manual"});
                $(cpb).tooltip('show');
                cpb.onmouseout=function(){$(cpb).tooltip('destroy')};
            } else{
                $(cpb).tooltip({title:"failed!", placement: "bottom", trigger: "manual"});
                $(cpb).tooltip('show');
                cpb.onmouseout=function(){$(cpb).tooltip('destroy')};
            }
        } catch(err){
            $(cpb).tooltip({title:"failed!", placement: "bottom", trigger: "manual"});
            $(cpb).tooltip('show');
            cpb.onmouseout=function(){$(cpb).tooltip('destroy')};
        }
    }
    复制代码

    用的时候直接

    <button id="cpbtn" onclick="copy('cptar', 'cpbtn')">copy</button>

    即可

     

    到此还没有结束。。。

    项目用的vue,于是需要做成vue的method,又是用coffee写的,改了下语法,在初次渲染的html中测试通过了,然后。。。我的copy妞是个vex模态框。。button是写在vex.dialog.open的message里的,message是个字符串,弹窗时候强注一段html。而且vue函数是只在渲染阶段绑定,所以。。。初次vue渲染的时候不会识别到字符串中的v-on:click,无法绑定。。于是不能从button元素直接调。

    决定搞一个隐藏input中继一下,最后终于用比较优美的姿势实现了。。。(上次是直接在message里强行注入script。。。涉及script嵌套还加了个转义<\/script>,结果丑的一bi。。)

    button里 οnclick="document.getElementById('copyrelay').select()",input里@select('copy(...)')(@是vue的v-on:的缩写)。

    终于测试一切完好,天真的以为加个display: none就大功告成。。结果发现跪了

    原来是display:none的元素并不能被select。。

    同样的,也不能focus, change等等,于是顺着onerror等事件挨个试了一遍。。发现貌似只有onclick work。。。

    另外还顺带试了一下,<input type="hidden"/>也是不能用那些事件;即使正常显示元素,value=""的话也不能触发select。

    当然,至于是.select()没有成功,还是元素没有触发select事件,还是没有触发v-on:select,有待确定,有时间可以试一下。

     

    Anyway,最终代码:

    <input id="copyrelay" style="display: none;" @click=“copy('cptg','cpbt')”/>
    
    <!--vex.dialog.open的message中:-->
    <input id="cpbt" type="button" onclick="document.getElementById('copyrelay').click()"/>
    <input id="cptg" value="copy test" readonly/>

    method中的copy函数如上所提,转为coffee。

     

    我这个伪frontend太弱了。。还是希望给贵司多搞点贡献。。。

    感谢lrx,lyy,P8,zzl,xxm犇们Orz。。。

    就这样。

     

     

     

     
     
     
    展开全文
  • 创建线程池的四种方式

    万次阅读 2019-02-22 09:41:40
    Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创建一个定长线程池,可...
  • 复制图片文件的4种方式

    千次阅读 2018-05-28 17:22:16
    复制图片文件的4种方式 * 复制图片 * * 分析: * 复制数据,如果我们知道用记事本打开并能够读懂,就用字符流,否则用字节流。 * 通过该原理,我们知道我们应该采用字节流。 * 而字节流有4种方式,所以做这个...
  • 使用字节流操作时文件,有四种方式,现对一个flac文件分别使用四种方式进行复制,测试其效率。测试类:public static void main(String[] args) throws IOException { long startTime = System.cur
  • Java 创建类的四种方式

    千次阅读 2020-10-11 21:53:51
    Java 创建类的四种方式 对于上学期已经学习过c++的同学,是不是对另一大编程语言产生了浓厚的兴趣,对于c++的面向对象编程,又和java的面向变量有何区别,下面我们从java四种创建对象来说起。 一:new运算的方式创建...
  • 但是我们很不喜欢写很多冗长的==b.setF1(a.getF1())==这样的代码,于是我们需要简化对象拷贝方式。 一、背景 1.1 对象拷贝概念 Java中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte...
  • java复制文件的4种方式

    千次阅读 2018-10-11 11:08:06
    这是最经典的方式将一个文件的内容复制到另一个文件中。 使用FileInputStream读取文件A的字节,使用FileOutputStream写入到文件B。 这是第一个方法的代码: 1 private static void copyFileUsingFileStreams...
  • Java对象的快速复制的几种方式

    万次阅读 2018-07-25 18:01:08
    浅拷贝、深度复制、BeanUtils.copyProperties() 对象的克隆是指创建一个新的对象,且新的对象的状态与原始对象的状态相同。当对克隆的新对象进行修改时,不会影响原始对象的状态。 注释:clone()是object类的...
  • MySQL复制详解

    千次阅读 2022-03-07 13:39:22
    复制种方式 1、基于语句的复制(Statement-Based Replication) 2、基于行的复制(Row-Based Replication) 五、复制所用到的文件 1、二进制文件 2、中继日志文件 3、备库连接到主库的信息 4、前备库复制的...
  • JAVA字节流实现复制文件的几种方式

    千次阅读 2019-02-08 21:19:23
    一、方式一 public static void demo1() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("res.jpg"); //创建输入流对象,关联res.jpg FileOutputStream fos ...
  • oracle 数据库扩容的四种方式

    千次阅读 2018-08-21 19:33:36
    1、新添加一个表空间 create smallfile tablespace "TBS4" datafile ‘/u02/app/oracle/oradata/orcl/tbs401.dbf’ size 10M ...reuse autoextend on next 50M, ...‘/u02/app/oracle/oradata/orcl/tbs...
  • 四种文件复制方式的效率比较 文件复制方式,字节流,一共4个方式,源文件的大小是:40.8 MB (42,885,472 字节) 1.字节流读写单个字节 运行时间:210546ms 2.字节流读写字节数组 运行时间:438ms 3.字节流缓冲区读写...
  • Java复制文件的4种方式

    万次阅读 2018-03-30 13:33:07
    java复制文件的4种方式 摘要 尽管Java提供了一个可以处理文件的IO操作类。 但是没有一个复制文件的方法。 复制文件是一个重要的操作,当你的程序必须处理很多文件相关的时候。 然而有几种方法可以进行Java文件复制...
  • Hive导入数据的四种方式

    千次阅读 2019-07-22 13:10:24
    1、从本地文件系统中导入数据到Hive...(1)是移动不是复制,hdfs中的teacher2.txt移动走了。 (2)如果有多个文件可以:load data inpath '/input/*' into table teacher; 3、从别的表中查询出相应的数据并导入到Hi...
  • Java中复制文件的4方法

    千次阅读 2021-02-12 09:05:36
    在这里,我们将了解学习可以在java中复制文件的四种不同方法。方法一:使用Stream这是java中传统的文件复制方式。这里创建两个文件 - source和destination。然后从source创建InputStream并使用OutputStream将它写入...
  • Java创建对象的四种方式

    千次阅读 2019-02-21 18:30:07
    Java创建对象的方式从是否调用了构造函数可以分为两 调用了构造函数 1)使用new关键字 2)使用Class类的newInstance方法: a.使用Class类的forName方法 b.使用ClassLoader类的loadClass方法 3)使用...
  • 谈容灾,谈灾备,我们总是不可避免的要提到复制技术。因为复制技术具有备份所不具备的切换优势(详见备份和复制的区别),能够得到更好的恢复点目标(PRO)和恢复时间...按照技术特点分为两模式:同步复制(又称实时复
  • 这篇文章主要介绍了java复制文件的4种方式,通过实例带给大家介绍了java 拷贝文件到另一个目录下的方法,需要的朋友可以参考下 尽管Java提供了一个可以处理文件的IO操作类。 但是没有一个复制文件的方法。 复制文件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 506,781
精华内容 202,712
关键字:

复制的四种方式