精华内容
下载资源
问答
  • Java复制文件并重命名

    2021-07-28 17:54:01
    Java虚拟机内存模型 Java虚拟机内存模型中定义的访问操作与物理计算机处理的基本一致! Java中通过多线程机制使得多个任务同时执行处理,所有的线程共享JVM内存区域main memory,而每个线程又单独的有自己的工作...

    Java虚拟机内存模型

    Java虚拟机内存模型中定义的访问操作与物理计算机处理的基本一致!

    Java中通过多线程机制使得多个任务同时执行处理,所有的线程共享JVM内存区域main memory,而每个线程又单独的有自己的工作内存,当线程与内存区域进行交互时,数据从主存拷贝到工作内存,进而交由线程处理(操作码+操作数)。更多信息我们会在后面的《深入JVM—JVM类执行机制中详细解说》。

    在之前,我们也已经提到,JVM的逻辑内存模型如下:

    我们现在来逐个的看下每个到底是做什么的!

    1、程序计数器

    程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

    由于Java 虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

    如果线程正在执行的是一个Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie 方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java 虚拟机规范中没有规定任何OutOfMemoryError 情况的区域。

    2、Java 虚拟机栈

    与程序计数器一样,Java 虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame ①)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

    经常有人把Java 内存区分为堆内存(Heap)和栈内存(Stack),这种分法比较粗糙,Java 内存区域的划分实际上远比这复杂。这种划分方式的流行只能说明大多数程序员最关注的、与对象内存分配关系最密切的内存区域是这两块。其中所指的“堆”在后面会专门讲述,而所指的“栈”就是现在讲的虚拟机栈,或者说是虚拟机栈中的局部变量表部分。

    局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress 类型(指向了一条字节码指令的地址)。

    其中64 位长度的long 和double 类型的数据会占用2 个局部变量空间(Slot),其余的数据类型只占用1 个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

    在Java 虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常;如果虚拟机栈可以动态扩展(当前大部分的Java 虚拟机都可动态扩展,只不过Java 虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError 异常。

    3、本地方法栈

    本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java 方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native 方法服务。虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如Sun HotSpot 虚拟机)直接就把本地方法栈和虚拟机栈合二为一。

    与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError 和OutOfMemoryError异常。

    4、Java 堆

    对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块。Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java 虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配①,但是随着JIT 编译器的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换②优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上也渐渐变得不是那么“绝对”了。

    Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC 堆”(GarbageCollected Heap,幸好国内没翻译成“垃圾堆”)。如果从内存回收的角度看,由于现在收集器基本都是采用的分代收集算法,所以Java 堆中还可以细分为:新生代和老年代;再细致一点的有Eden 空间、From Survivor 空间、To Survivor 空间等。如果从内存分配的角度看,线程共享的Java 堆中可能划分出多个线程私有的分配缓冲区(Thread LocalAllocation Buffer,TLAB)。不过,无论如何划分,都与存放内容无关,无论哪个区域,存储的都仍然是对象实例,进一步划分的目的是为了更好地回收内存,或者更快地分配内存。在本章中,我们仅仅针对内存区域的作用进行讨论,Java 堆中的上述各个区域的分配和回收等细节将会是下一章的主题。

    根据Java 虚拟机规范的规定,Java 堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms 控制)。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常。

    4、方法区

    方法区(Method Area)与Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java 堆区分开来。

    对于习惯在HotSpot 虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为“永久代”(Permanent Generation),本质上两者并不等价,仅仅是因为HotSpot 虚拟机的设计团队选择把GC 分代收集扩展至方法区,或者说使用永久代来实现方法区而已。对于其他虚拟机(如BEA JRockit、IBM J9 等)来说是不存在永久代的概念的。即使是HotSpot 虚拟机本身,根据官方发布的路线图信息,现在也有放弃永久代并“搬家”至Native Memory 来实现方法区的规划了。

    Java 虚拟机规范对这个区域的限制非常宽松,除了和Java 堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入了方法区就如永久代的名字一样“永久”存在了。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说这个区域的回收“成绩”比较难以令人满意,尤其是类型的卸载,条件相当苛刻,但是这部分区域的回收确实是有必要的。在Sun 公司的BUG 列表中,曾出现过的若干个严重的BUG 就是由于低版本的HotSpot 虚拟机对此区域未完全回收而导致内存泄漏。

    根据Java 虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError 异常。

    5、运行时常量池

    运行时常量池(Runtime Constant Pool)是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池(Constant PoolTable),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

    Java 虚拟机对Class 文件的每一部分(自然也包括常量池)的格式都有严格的规定,每一个字节用于存储哪种数据都必须符合规范上的要求,这样才会被虚拟机认可、装载和执行。但对于运行时常量池,Java 虚拟机规范没有做任何细节的要求,不同的提供商实现的虚拟机可以按照自己的需要来实现这个内存区域。不过,一般来说,除了保存Class 文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中①。

    运行时常量池相对于Class 文件常量池的另外一个重要特征是具备动态性,Java 语言并不要求常量一定只能在编译期产生,也就是并非预置入Class 文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用得比较多的便是String 类的intern() 方法。

    既然运行时常量池是方法区的一部分,自然会受到方法区内存的限制,当常量池无法再申请到内存时会抛出OutOfMemoryError 异常

    6、直接内存

    直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError 异常出现,所以我们放到这里一起讲解。

    在JDK 1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用Native 函数库直接分配堆外内存,然后通过一个存储在Java 堆里面的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java 堆和Native 堆中来回复制数据。

    显然,本机直接内存的分配不会受到Java 堆大小的限制,但是,既然是内存,则肯定还是会受到本机总内存(包括RAM 及SWAP 区或者分页文件)的大小及处理器寻址空间的限制。服务器管理员配置虚拟机参数时,一般会根据实际内存设置-Xmx等参数信息,但经常会忽略掉直接内存,使得各个内存区域的总和大于物理内存限制(包括物理上的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常

    逻辑内存模型我们已经看到了,那当我们建立一个对象的时候是怎么进行访问的呢?在Java 语言中,对象访问是如何进行的?对象访问在Java 语言中无处不在,是最普通的程序行为,但即使是最简单的访问,也会却涉及Java 栈、Java 堆、方法区这三个最重要内存区域之间的关联关系,如下面的这句代码:

    Object obj = new Object();

    假设这句代码出现在方法体中,那“Object obj”这部分的语义将会反映到Java 栈的本地变量表中,作为一个reference 类型数据出现。而“new Object()”这部分的语义将会反映到Java 堆中,形成一块存储了Object 类型所有实例数据值(Instance Data,对象中各个实例字段的数据)的结构化内存,根据具体类型以及虚拟机实现的对象内存布局(Object Memory Layout)的不同,这块内存的长度是不固定的。另外,在Java 堆中还必须包含能查找到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,这些类型数据则存储在方法区中。

    由于reference 类型在Java 虚拟机规范里面只规定了一个指向对象的引用,并没有定义这个引用应该通过哪种方式去定位,以及访问到Java 堆中的对象的具体位置,因此不同虚拟机实现的对象访问方式会有所不同,主流的访问方式有两种:使用句柄和直接指针。

    句柄池

    如果使用句柄访问方式,Java 堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息,如下图所示。

    如果使用直接指针访问方式,Java 堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,reference 中直接存储的就是对象地址,如下图所示

    这两种对象的访问方式各有优势,使用句柄访问方式的最大好处就是reference 中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference 本身不需要被修改。

    使用直接指针访问方式的最大好处就是速度更快,它节省了一次指针定位的时间开销,由于对象的访问在Java 中非常频繁,因此这类开销积少成多后也是一项非常可观的执行成本。就本书讨论的主要虚拟机Sun HotSpot 而言,它是使用第二种方式进行对象访问的,但从整个软件开发的范围来看,各种语言和框架使用句柄来访问的情况也十分常见。

    下面我们来看几个示例

    1、Java 堆溢出

    下面的程中我们限制Java 堆的大小为20MB,不可扩展(将堆的最小值-Xms 参数与最大值-Xmx 参数设置为一样即可避免堆自动扩展),通过参数-XX:+HeapDumpOnOutOfMemoryError 可以让虚拟机在出现内存溢出异常时Dump 出当前的内存堆转储快照以便事后进行分析。

    参数设置如下

    最后

    如何获取免费架构学习资料?

    资料获取方式:点击下方蓝色传送门

    Java学习、面试;文档、视频资源免费获取

    由于篇幅原因,就不多做展示了
    …(img-sg2uxMaO-1627466025099)]

    [外链图片转存中…(img-B9o8Ntvv-1627466025100)]

    [外链图片转存中…(img-8SS8iZT7-1627466025101)]

    由于篇幅原因,就不多做展示了

    展开全文
  • 新老系统数据对接,需要把老系统的附件放到新系统中,新系统的表结构和文件的存储位置与老系统都不同,存储方式也不一样。现需要把老系统的附件做做调整

    背景: 新老系统数据对接,需要把老系统的附件放到新系统中,新系统的表结构和文件的存储位置与老系统都不同,存储方式也不一样。老系统是按月份存储了所有附件,并且文件是 id . 文件类型(id 是这个附件在表中记录的 id)。在新系统中,所有附件是放在了同一个文件夹,文件是 附件名称-时间戳 . 文件类型。

    任务: 把附件命名规则改成新系统的规则,并且需要把同一个项目的附件放到同一个文件夹中,该文件夹的名称为项目名称。

    解决步骤:
    用到的 jar 包:fastjson-1.2.62.jar

    1)把项目与附件的关系整理出来,调整格式,形成如下文件。

    • path:附件在老系统的位置
    • proname:项目名称
    • fileName:附件名称

    在这里插入图片描述
    2)写转换程序

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.Reader;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    
    public class Test {
    	public static void main(String[] args) {
    	
    		String path = Test.class.getClassLoader().getResource("oldfiles.json").getPath();
            String s = readJsonFile(path);
            JSONObject allfiles = JSON.parseObject(s);
            
            JSONArray links = allfiles.getJSONArray("alldata");
    
            for (int i = 0 ; i < links.size();i++){
                JSONObject datakey = (JSONObject)links.get(i);
                String filepath = (String)datakey.get("path");
                String proname = (String)datakey.get("proname");
                String fileName = (String)datakey.get("fileName");
                System.out.println(filepath);
                System.out.println(proname);
                System.out.println(fileName);
                renameFile(proname, filepath, fileName);
            }
            
    		
    		
    		System.out.println("------------over------------");
    	}
    	
    	// 移动文件并更改文件名称
    	public static void renameFile(String proname, String path, String fileName) {
    		String dirName = "E:/newattachs/" + proname;
    		File dir = new File(dirName);
    		if(!dir.exists()) {
    			//如果该项目名称文件夹未创建,则创建
    			dir.mkdir();
    			System.out.println(dirName + "创建成功--------");
    		}
    		
    		//获取旧文件
    		File file = new File(path);
    		String newFilename = "E:/newattachs/" + proname + "/" + fileName;
    		file.renameTo(new File(newFilename));
    	}
    	
    	// 读取json文件,返回json串
        public static String readJsonFile(String fileName) {
            String jsonStr = "";
            try {
                File jsonFile = new File(fileName);
                FileReader fileReader = new FileReader(jsonFile);
    
                Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
                int ch = 0;
                StringBuffer sb = new StringBuffer();
                while ((ch = reader.read()) != -1) {
                    sb.append((char) ch);
                }
                fileReader.close();
                reader.close();
                jsonStr = sb.toString();
                return jsonStr;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
    
    }
    

    3)确保 newattachs 文件夹已创建,执行这个 main 方法即可
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    大致步骤就这些了,具体的细节可灵活修改
    如果朋友有更好的想法、更好的实现方式,还请留言指教

    展开全文
  • Java文件加密压缩 添加文件加密压缩工具包依赖 <!-- zip4j压缩工具 --> <dependency> <groupId>net.lingala.zip4j</groupId> <artifactId>zip4j</artifactId> <...

    Java 多文件加密压缩

    添加文件加密压缩工具包依赖

    <!-- zip4j压缩工具  -->
            <dependency>
                <groupId>net.lingala.zip4j</groupId>
                <artifactId>zip4j</artifactId>
                <version>1.3.2</version>
            </dependency>
    

    话不多说,直接上干货

    完整代码如下:

     package com.rhtcms.cms.api.admin.main;
    
    import org.json.JSONObject;
    import org.springframework.stereotype.Controller;
    
    import net.lingala.zip4j.core.ZipFile;
    import net.lingala.zip4j.exception.ZipException;
    import net.lingala.zip4j.model.ZipParameters;
    import net.lingala.zip4j.util.Zip4jConstants;
    
    import java.io.*;
    import java.util.*;
    
    public class FileCompressionApiAct {
        /**
         * 复制压缩文件路径  ps:此路径必须为空文件夹,在压缩完成后此文件夹将被清空目录
         */
        private static String copyPath = "c:/Users/Administrator/Desktop/压缩测试/压缩测试作业复制";
    
        private static long time = System.currentTimeMillis();//以时间戳作为文件名,防止重命名问题
    
        /**
         * 压缩包路径: 路径+压缩包名称    eg: C:/Users/Administrator/Desktop/压缩测试/  +  test.zip
         */
        private static String zipPath = "C:/Users/Administrator/Desktop/压缩测试/" + time + ".zip";
    
        /**
         * 可支持的压缩文件格式
         */
        private static String[] fileType = {"doc", "docx", "pdf", "txt"};
    
        /**
         * @param filePath   压缩文件路径
         * @param fileRename 压缩文件重命名名称
         * @param password   加密密码
         * @return
         * @Title: zipFilesAndEncrypt
         * @Description: 将指定路径下的文件压缩至指定zip文件,并以指定密码加密,若密码为空,则不进行加密保护
         * @Author: 张庆裕
         * @Date: 2021/01/04
         */
        //@RequestMapping("/fileCompression/list")
        public String zipFilesAndEncrypt(List<File> filePath, List<String> fileRename, String password) {
            /**
             * 压缩成功的文件数量
             */
            int successCount = 0;
            /**
             * 压缩失败的文件数量
             */
            int failCount = 0;
            /**
             * 返回数据
             */
            JSONObject ob = new JSONObject();
    
            ArrayList<String> failFile = new ArrayList<>();//压缩失败的文件路径
    
            ArrayList<String> failFilePath = new ArrayList<>();//路径错误的文件
    
            ArrayList<File> filesToAdd = new ArrayList<>();//压缩路径的集合
    
            //创建复制文件夹
            File folder = new File(copyPath);
            if(!folder.exists()){//如果文件夹不存在
                boolean mkdir = folder.mkdir();//创建文件夹
                if(!mkdir){//系统未找到该路径
                    throw new RuntimeException("复制文件路径出错,请修改复制文件夹路径");
                }
            }else{//文件夹存在
                File[] listFiles = folder.listFiles();
                if(listFiles.length > 0){//如何文件夹下存在目录则,停止压缩,防止删除其他文件
                    throw new RuntimeException("复制的文件夹不为空,请选择空文件夹!");
                }
            }
    
            for (int i = 0; i < filePath.size(); i++) {//遍历压缩文件数据
                File file = filePath.get(i);//获取原文件
                if (!file.exists()) {//防止文件异常,首先再次确认文件路径是否存在
                    // 文件不存在
                    failCount++;
                    failFilePath.add(file.getPath());
                    System.out.println("文件:" + file.getPath() + "  路径不存在!");
                    ob.put("failFilePath", failFilePath);
                } else {//文件存在
                    //获取原文件路径
                    String path = filePath.get(i).getPath();
                    //获取最后一个点的位置
                    int lastIndexOf = path.lastIndexOf(".");
                    //获取文件后缀 eg: txt , doc , pdf ....
                    String suffix = path.substring(lastIndexOf + 1);
                    if (Arrays.asList(fileType).contains(suffix)) {     //判断文件格式是否合格,合格添加至压缩文件中
                        //获取原文件名称
                        File oldName = new File(file.getPath());
    
                        //先复制文件
                        File newName = new File(copyPath + "/" + file.getName());
                        try {
                            copyFile(oldName, newName);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //String path = newName.getPath();//获取复制文件的路径
                        String parentPath = newName.getParent();//获取复制出来的文件的父级目录
                        String reName = fileRename.get(i);//获取重命名的名称
    
                        newName.renameTo(new File(parentPath + "/" + reName));//重命名复制出来的文件
                        filesToAdd.add(new File(parentPath + "/" + reName));//将赋值出来的文件添加到压缩文件集合中
                        successCount++;//压缩成功文件数量+1
                    } else {
                        failFile.add(file.getPath());
                        failCount++;//压缩失败文件数量+1
    
                        ob.put("filePath", failFile);
                        System.out.println("该文件压缩失败:" + file.getPath() + " 文件格式错误!");
                    }
                }
            }
            //压缩配置
            try {
                ZipParameters parameters = new ZipParameters();
                parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);//压缩方式
                //设置压缩级别
                //DEFLATE_LEVEL_FASTEST - 最低压缩级别,但压缩速度更高
                //DEFLATE_LEVEL_FAST - 低压缩级别,但压缩速度更高
                //DEFLATE_LEVEL_NORMAL - 压缩水平速度之间的最佳平衡
                //DEFLATE_LEVEL_MAXIMUM - 高压缩级别,但速度不佳
                //DEFLATE_LEVEL_ULTRA - 最高压缩级别但速度较低
                parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);//压缩级别
                if (password != null && password!="") {
                    parameters.setEncryptFiles(true);//设置压缩文件加密
                    parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);//加密方式
                    parameters.setPassword(password);//设置加密密码
                }
                ZipFile zipFile = new ZipFile(zipPath);//创建压缩路径
                zipFile.setFileNameCharset("gbk");//设置压缩编码
                zipFile.addFiles(filesToAdd, parameters);//添加压缩文件并进行加密压缩
                //压缩完成后清空复制的文件目录
                deleteDir(copyPath);
                ob.put("zipPath", zipPath);
                ob.put("successCount", successCount);
                ob.put("failCount", failCount);
            } catch (ZipException e) {
                //清空复制的文件目录
                deleteDir(copyPath);
                ob.put("unKnown", "未知异常,压缩失败!");
                System.out.println("文件压缩出错");
                e.printStackTrace();
            }
            return ob.toString();
        }
    
        /**
         * @Description: 文件复制
         * @Param: resource  原文件路径
         * @Param: target    新文件路径
         * @return:
         * @Author: 张庆裕
         * @Date: 2021/1/6
         */
        public void copyFile(File resource, File target) throws Exception {
            // 输入流 --> 从一个目标读取数据
            // 输出流 --> 向一个目标写入数据
            long start = System.currentTimeMillis();
            // 文件输入流并进行缓冲
            FileInputStream inputStream = new FileInputStream(resource);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            // 文件输出流并进行缓冲
            FileOutputStream outputStream = new FileOutputStream(target);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
            // 缓冲数组
            // 大文件 可将 1024 * 2 改大一些,但是 并不是越大就越快
            byte[] bytes = new byte[1024 * 2];
            int len = 0;
            while ((len = inputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, len);
            }
            // 刷新输出缓冲流
            bufferedOutputStream.flush();
            //关闭流
            bufferedInputStream.close();
            bufferedOutputStream.close();
            inputStream.close();
            outputStream.close();
            long end = System.currentTimeMillis();
            System.out.println("复制文件:" + resource.getPath() + "  成功 耗时:" + (end - start) / 1000 + " s");
        }
    
        /**
         * @Description: 清空复制压缩文件下的内容
         * @Param: path 复制文件夹的路径
         * @return:
         * @Author: 张庆裕
         * @Date: 2021/1/6
         */
        public boolean deleteDir(String path) {
            File file = new File(path);
            if (!file.exists()) {//判断是否待删除目录是否存在
                System.err.println("The dir are not exists!");
                return false;
            }
            String[] content = file.list();//取得当前目录下所有文件和文件夹
            for (String name : content) {
                File temp = new File(path, name);
                if (temp.isDirectory()) {//判断是否是目录
                    deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
                    temp.delete();//删除空目录
                } else {
                    if (!temp.delete()) {//直接删除文件
                        System.err.println("Failed to delete " + name);
                    }
                }
            }
            return true;
        }
    
    
        /**
         * @Description: 文件压缩测试接口
         * @Param:
         * @return:
         * @Author: 张庆裕
         * @Date: 2021/1/7
         */
        public static void main(String[] args) {
            List<File> filePath = new ArrayList<>();//压缩文件路径
            filePath.add(new File("C:/Users/Administrator/Desktop/压缩测试/yasuo/OA平台问题.docx"));
            filePath.add(new File("C:/Users/Administrator/Desktop/压缩测试/yasuo/OA平台问题1.docx"));
            filePath.add(new File("C:/Users/Administrator/Desktop/压缩测试/yasuo/OA平台问题2.docx"));
            filePath.add(new File("C:/Users/Administrator/Desktop/压缩测试/yasuo/OA平台问题3.docx"));
            filePath.add(new File("C:/Users/Administrator/Desktop/压缩测试/yasuo/邮箱1.md"));
            filePath.add(new File("C:/Users/Administrator/Desktop/压缩测试/yasuo/邮箱2.md"));
    
            List<String> fileRename = new ArrayList<>();//压缩文件重命名名称
            fileRename.add("oa平台问题.docx");
            fileRename.add("oa平台问题1.docx");
            fileRename.add("oa平台问题2.docx");
            fileRename.add("oa平台问题3.docx");
            fileRename.add("邮箱副本1.md");
            fileRename.add("邮箱副本2.md");
    
            String password = "123456";//加密密码
            //请在单元测试进行测试, 或者将方法改为 static 方法
            //String result = zipFilesAndEncrypt(filePath, fileRename, password);
            //System.out.println(result);
        }
    
    }
    
    
    

    效果如下:
    在这里插入图片描述

    在这里插入代码片
    
    展开全文
  • /* * 将D盘com文件夹中后缀为java的文件名后缀改为jad结尾的并复制到E盘中 * * 思路: * *  A:封装目录和目的地 *  B:获取目录下所有的后缀名为java文件 * C:复制文件到E盘 * D:修改后...

    对于文件的操作,我们一定要明确的是该路径是可以指向特定的文件的,否则会报FileNoFoundException

    File 的操作实质上是有文件的操作。


    /*

     * 将D盘com文件夹中后缀为java的文件名后缀改为jad结尾的并复制到E盘中
     * 
     * 思路:
     * 
     *  A:封装目录和目的地
     *  B:获取目录下所有的后缀名为java的文件
     *      C:复制该文件到E盘
     *      D:修改后缀名
     *  
     */

    import java.io.BufferedReader;

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;


    public class RenameDemo {
    public static void main(String[] args) throws IOException {
    //封装目录和目的地
    File srcFolder = new File("D:\\com");
    File destFolder = new File("E:\\com");

    if (!destFolder.exists()) {
    destFolder.mkdir();
    }

    copyFile(srcFolder, destFolder);

    rename(destFolder);


    }

    private static void rename(File destFolder) {
    //获取目录下所有的后缀名为java的文件
    File[] fileArr = destFolder.listFiles();
    for(File file : fileArr){
    if(file.isDirectory()){
    rename(file);
    }else{
    String name = file.getAbsolutePath();
    int index = name.indexOf('.');
    String start = name.substring(0, index);
    String newName = start+".jad";
    File newFile = new File(newName);
    file.renameTo(newFile);

    }
    }
    }


    public static void copyFile(File srcFolder,File destFolder) throws IOException{
    //获取目录下所有的后缀名为java的文件
    File[] fileArr = srcFolder.listFiles();
    for(File file:fileArr){
    if (file.isDirectory()) {
    String name = file.getName();
    File newFile = new File(destFolder,name);
    newFile.mkdir();
    copyFile(file, newFile);
    }else{
    if(file.getName().endsWith(".java")){
    String name = file.getName();
    File newFile = new File(destFolder,name);

    BufferedReader br = new BufferedReader(new FileReader(file));
    BufferedWriter bw = new BufferedWriter(new FileWriter(newFile));

    String line;
    while((line = br.readLine()) != null){
    bw.write(line);
    bw.newLine();
    bw.flush();
    }

    bw.close();
    br.close();
    }
    }
    }

    }
    }
    展开全文
  • Java复制文件命名的超简洁写法

    千次阅读 2016-04-02 13:06:01
    没错又是我,这次为大家带来Java复制文件命名的超简洁写法(请确保你的jre在1.8+),这次用到了Files(始于1.7)和lambda 表达式(始于1.8),都是比较新的东西,同时还有一些振奋人心的特性(和爱)。...
  • java文件内容输出到新文件并重名为.h文件 #!/usr/bin/perl my $indir = $ARGV[0]; &find_fileindir("$indir"); sub find_fileindir(){ #print "$dir\n"; local($dir) = @_; opendir(DIR,"$dir"|| die "can...
  • cp 在本文件夹复制并重命名

    千次阅读 2020-11-08 22:40:20
    cp 在本文件夹复制并重命名 cp aa.txt bb.txt
  • 使用renameTo()进行移动和重命名操作,注:该方法无法覆盖重名文件,需用delete()删除再使用renameTo()操作。 package eg2; import java.io.File; import java.util.Scanner; /****************** * 文件的移动...
  • 需求很简单,程序也不难。看到题目之后,自己第一次没有使用eclipse,而是...import java.io.*; class Copy{ public void copy(String srcPath, String targetPath) throws Exception{ File srcFolder = new Fi
  • * 将单级目录H:\\aa 目录下,.java 复制到 h:\\bb,并重命名为.jdg文件 * @author ZYxiao * */ public class FileCopyRename { public static void main(String[] args) throws IOException{ File inputFile =
  • import java.io.*; import java.nio.file.Files; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.*; /** * 把某个文件夹下的...
  • 将当前目录的所有java文件内容拷贝到新文件并重命名.h文件 opendir(DIR, '.') or die "无法打开目录, $!"; foreach $filename (sort grep(/^.*\.java$/,readdir(DIR))){ #$filename = _; my @fields = split /....
  • Java 复制文件并改名

    千次阅读 2018-02-12 11:35:16
    //引入包import java.io.File;import java.io.FileInputStream;...//获取文件目录并复制文件String url1 = getFullFilePath(D:\\a.txt); //目标文件String url2 = getFullFilePath(E:\\b.txt); //要赋值的路径及...
  • 如这些文件夹下全部都是png的图片,要想把他们全部...使用java代码: package com.company; import java.io.*; public class Main { public static void main(String[] args) throws IOException { File fil...
  • import java.util.ArrayList; import java.util.List; import java.io.File; import java.io.FileWriter; import java.io.IOException;...public class EnameToTXT { ... 将字符串写入文件末尾,一字符串一换行 .
  • /** * 用缓冲区读写,来提升读写效率。 */ private static void fileCopyRightWay() { FileWriter fw = null; FileReader fr = null; try { fr = new FileReader("D:/test/我是.co...
  • JAVA File实现重命名文件复制文件夹、拷贝文件 public static void main(String[] args) { // 要读取的文件夹路径 String filepath = "C:\\Users\\admin\\Desktop\\logo"; File file = new File...
  • java项目复制后重新命名方法

    千次阅读 2017-06-21 13:23:57
    1.复制原项目文件夹,然后重新命名XXX 2.打开sts点击”File“----------点击“import"------选择”General Existing Projects into Workpace" 3.右击XXX--------点击“Properties”----------点击“Web Project ...
  • Java字节流代码复制文件 复制文件主要用到的是IO流的知识,不论是复制文本还是复制图片,道理都是一样的,只不过是改下后缀。 下面有几种复制文件的代码,亲测运行良好,希望能给各位带来帮助 字节流复制文本文件 ...
  • 主要介绍了java读取excel文件并复制文件到指定目录示例,需要的朋友可以参考下
  • 当前目录下有一个名为music.flac文件,若想复制文件并重命名为music.flac,该如何实现呢?(该文件大小为9336KB) public class TestCopyFile { /* * File类中的RandomAccessFile可以对文件进行随机读写操作,使用...
  • packagecn.java.test; importjava.io.BufferedReader; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileOutputStream; i...
  • 需求:收到广播后拷贝 /data/vendor/logs/ 下面最新的文件夹到 /sdcard/tmp 下并重命名为 txt后缀 思路: 1.拷贝 /data/vendor/logs/ 到 /sdcard/tmp 2.筛选出最新的文件夹,删除其他文件夹 3.遍历最新文件夹下...
  • import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class A { public static void main(String[] args) throws Exception { String url1 = "D:\\a.txt"....
  • java文件复制,重命名

    千次阅读 2016-02-20 16:34:16
    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.IOException; pub
  • java实现文件拷贝,以及修改文件扩展名 一、文件拷贝 public File createNewFile(String path, String realPath, String newFileName) { File file = new File(path); // path原文件路径,被复制文件 File ...
  • 结果问题就是,因为是以班级为单位收集的,导致统计时候文件夹一层套一层,非常难挑自己的文件在哪。 于是写了这个程序。 前提是都是文件夹,而且文件名有独特的字符段。 import java.io.File; import java.io....
  • java基于eclipse实现文件复制,粘贴,剪切 大家好,我是小鱼儿.yanxiao,非常荣幸各位来到我的博客。最近放寒假了,闲的有点x疼,又回到了学习状态,今天分享一波代码,若是喜欢本篇文章记得三连一波,也欢迎大家发言。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,779
精华内容 1,911
关键字:

java复制文件并重命名

java 订阅