Java提取两个文件夹中的有差异的文件并生成相应的shell脚本
来源:互联网 发布:淘宝品质保障怎么设置 编辑:程序博客网 时间:2024/05/19 22:03
在实际部署过程中,经常会遇到因为网速慢的原因导致上传war包的过程令人发指。笔者也因此事苦恼过,数次建议运维提网速无果后,特想出如下策略:
1. 比较两个war中的所有文件,以下new代表新war包,old代表线上的旧war包;
2. new中有的old没有的,直接复制;
3. new中有的old也有的,复制并覆盖;
4. new中没有的old有的,则删除;
5. 把有差异的文件移到_tmp目录中;
6. 在_tmp目录中生成相应的shell脚本用于复制、删除文件;
以下是对应的Java代码:
package alan_test;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.channels.FileChannel;/** * 比较new和old两个目录中的所有文件且new的同级生成新的_tmp目录,存放有差异的文件,并生成相应的shell脚本 * 1. new中有的old没有的,直接复制 * 2. new中有的old也有的,复制并覆盖 * 3. new中没有的old有的,则删除 * * @author Alan * @date 2016年4月13日 下午4:48:39 * @version 2016年4月13日 Alan */public class CompareTwoDirectory { /** * 比较两个文件夹中的文件是否相同 * 注意:传入的路径请用"\\"分割(windows下,linux未验证) * * @param newDirectory * 新目录 * @param oldDirectory * 旧目录 */ public static void compare( String newDirectory, String oldDirectory ) { // 从旧目录中取得工程名称 String[] oldDirectoryArray = oldDirectory.split("\\\\"); String projectName = oldDirectoryArray[oldDirectoryArray.length - 1]; compare(newDirectory, oldDirectory, projectName); } /** * 比较两个文件夹中的文件是否相同 * 注意:传入的路径请用"\\"分割(windows下,linux未验证) * * @param newDirectory * 新目录 * @param oldDirectory * 旧目录 * @param projectName * 工程名称 */ public static void compare( String newDirectory, String oldDirectory, String projectName ) { final String newDir = dealDirectoryLastChar(newDirectory); final String oldDir = dealDirectoryLastChar(oldDirectory); // 按projectName在newDir同级建立一个新的目录 final String projectDir = createProjectDirectory(newDir, projectName); StringBuilder command = new StringBuilder(); System.out.println("开始比较:++++++++++++++++++++++++++++++++++" + System.currentTimeMillis()); // 第一遍循环,把在new中与old中不同的文件的提取出来 getFiles(newDir, new Call() { @Override public void call( Object... objects ) { if(objects[0] instanceof File) { File newFile = (File) objects[0]; String oldPath = newFile.getAbsolutePath().replace(newDir, oldDir); File oldFile = new File(oldPath); // 如果存在,则比较两个文件的MD5是否一样,不一样,复制并覆盖旧文件的 if(oldFile.exists()) { try { String newMd5 = MD5Util.getFileMD5String(newFile); String oldMd5 = MD5Util.getFileMD5String(oldFile); if(!newMd5.equals(oldMd5)) { System.out.println("copy and cover new File to : " + oldPath); copyFile(newFile, newFile.getAbsolutePath().replace(newDir, projectDir)); // linux下cp命令如果复制的是相同的文件,可能无法覆盖,所以此处使用先删除再复制的命令 command.append("rm -f ../" + projectName + oldPath.replace(oldDir, "") + "\n"); command.append("cp -f " + oldPath.replace(oldDir + "\\", "") + " ../" + projectName + oldPath.replace(oldDir, "") + "\n"); } } catch(Exception e) { System.err.println("生成MD5时出错!"); e.printStackTrace(); } } else { System.out.println("add new File to : " + oldPath); copyFile(newFile, newFile.getAbsolutePath().replace(newDir, projectDir)); command.append("cp -f " + oldPath.replace(oldDir + "\\", "") + " ../" + projectName + oldPath.replace(oldDir, "") + "\n"); } } } }); // 第二遍循环,把在old中不在new中的文件提取出来,这部分说明是要删除的文件 getFiles(oldDir, new Call() { @Override public void call( Object... objects ) { if(objects[0] instanceof File) { File oldFile = (File) objects[0]; String newPath = oldFile.getAbsolutePath().replace(oldDir, newDir); File newFile = new File(newPath); // 如果新文件不存在,则删除旧文件 if(!newFile.exists()) { System.out.println("delete old File from : " + oldFile.getAbsolutePath()); command.append("rm -f ../" + projectName + newPath.replace(newDir, "") + "\n"); } } } }); System.out.println("结束比较:++++++++++++++++++++++++++++++++++" + System.currentTimeMillis()); System.out.println("生成的shell命令如下:"); System.out.println(command.toString().replace("\\", "/")); createCommandFile(projectDir, command.toString().replace("\\", "/")); } private static void createCommandFile( String dir, String command ) { File file = new File(dir + "\\command.sh"); try { file.createNewFile(); FileOutputStream output = new FileOutputStream(file); output.write(command.getBytes()); output.close(); } catch(IOException e) { System.err.println("创建command文件时出错:" + file.getAbsolutePath()); e.printStackTrace(); } } private static String createProjectDirectory( String newDir, String projectName ) { File file = new File(newDir); String projectDirectory = file.getParent() + "\\" + projectName + "_tmp"; File projectFile = new File(projectDirectory); if(!projectFile.exists() || !projectFile.isDirectory()) { projectFile.mkdir(); } else { boolean delete = deleteDirectory(projectFile); if(delete) { projectFile.mkdir(); } else { System.err.println("已存在目录" + projectDirectory + "且删除失败!"); } } return projectDirectory; } private static boolean deleteDirectory( File dir ) { if(dir.isDirectory()) { String[] children = dir.list(); // 递归删除目录中的子目录下 for( int i = 0; i < children.length; i++ ) { boolean success = deleteDirectory(new File(dir, children[i])); if(!success) { return false; } } } // 目录此时为空,可以删除 return dir.delete(); } private static void copyFile( File srcFile, String desFilePath ) { File desFile = new File(desFilePath); File parentFile = new File(desFile.getParent()); if(!parentFile.exists()) { parentFile.mkdirs(); } try { desFile.createNewFile(); } catch(IOException e) { System.err.println("创建目标文件失败:" + desFilePath); e.printStackTrace(); } writeFile(srcFile, desFile); } private static void writeFile( File srcFile, File desFile ) { FileInputStream input = null; FileOutputStream output = null; FileChannel in = null; FileChannel out = null; try { input = new FileInputStream(srcFile); output = new FileOutputStream(desFile); in = input.getChannel(); out = output.getChannel(); in.transferTo(0, in.size(), out); } catch(Exception e) { System.err.println("写文件时出错:" + desFile.getAbsolutePath()); e.printStackTrace(); } finally { try { input.close(); output.close(); in.close(); out.close(); } catch(IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private static void getFiles( String filePath, Call call ) { filePath = dealDirectoryLastChar(filePath); File root = new File(filePath); File[] files = root.listFiles(); for( File file : files ) { if(file.isDirectory()) { getFiles(file.getAbsolutePath(), call); } else { if(call != null) { call.call(file); } } } } private static String dealDirectoryLastChar( String directory ) { if(directory.endsWith("\\")) { return directory.substring(0, directory.length() - 1); } return directory; } public static void main( String[] args ) { compare("E:\\test\\newWar\\", "E:\\test\\oldWar"); // getFiles("E:/data", new Call() { // @Override // public void call( Object... objects ) { // if(objects[0] instanceof File) { // System.out.println(( (File) objects[0] ).getAbsolutePath()); // } // } // }); }}interface Call { void call( Object... objects );}
基于以上程序,需要先在E:\test目录下新建newWar和oldWar两个目录,并添加一些文件,也可以修改main方法中compare的两个路径参数,运行结果如下:
开始比较:++++++++++++++++++++++++++++++++++1460538009097add new File to : E:\test\oldWar\logs\b.vsdxcopy and cover new File to : E:\test\oldWar\logs\fcuh-mall\fcuh-mall-20160201-0.logcopy and cover new File to : E:\test\oldWar\logs\fcuh-mall\fcuh-mall.logcopy and cover new File to : E:\test\oldWar\logs\fcuh-user\fcuh-user.logcopy and cover new File to : E:\test\oldWar\logs\fcuh-wechat\fcuh-wechat.logdelete old File from : E:\test\oldWar\b.jnt结束比较:++++++++++++++++++++++++++++++++++1460538010029生成的shell命令如下:cp -f logs/b.vsdx ../oldWar/logs/b.vsdxrm -f ../oldWar/logs/fcuh-mall/fcuh-mall-20160201-0.logcp -f logs/fcuh-mall/fcuh-mall-20160201-0.log ../oldWar/logs/fcuh-mall/fcuh-mall-20160201-0.logrm -f ../oldWar/logs/fcuh-mall/fcuh-mall.logcp -f logs/fcuh-mall/fcuh-mall.log ../oldWar/logs/fcuh-mall/fcuh-mall.logrm -f ../oldWar/logs/fcuh-user/fcuh-user.logcp -f logs/fcuh-user/fcuh-user.log ../oldWar/logs/fcuh-user/fcuh-user.logrm -f ../oldWar/logs/fcuh-wechat/fcuh-wechat.logcp -f logs/fcuh-wechat/fcuh-wechat.log ../oldWar/logs/fcuh-wechat/fcuh-wechat.logrm -f ../oldWar/b.jnt
生成的oldWar_tmp目录结构如下:
生成的shell文件如下:
注:代码中生成的shell脚本中的复制并覆盖使用的是先rm再cp,因为部分linux系统中cp是cp -i的别名,使用cp不一定覆盖的了原文件,为保险起见,先移除再复制。
0 0
- Java提取两个文件夹中的有差异的文件并生成相应的shell脚本
- 打开文件夹并选中相应的文件
- git提取出两个版本之间的差异文件并打包
- git提取出两个版本之间的差异文件并打包
- git提取出两个版本之间的差异文件并打包
- git提取出两个版本之间的差异文件并打包
- git提取出两个版本之间的差异文件并打包
- git提取出两个版本之间的差异文件并打包
- git提取出两个版本之间的差异文件并打包命令
- shell diff 比较两个文件的差异
- Java读取一个xml文件并生成相应的类
- c语言读取文件夹中的各个文件名,并删除相应的文件
- Beyond Compare脚本:比较文件并生成html格式的差异报告
- Android Studio开发环境创建aidl文件,并生成相应的java文件
- Linux生成以当前时间年/月/日命名的文件夹并向相应目录文件中写数据例程
- 两个处理文件的shell脚本
- 高效生成差异的脚本
- 利用shell脚本遍历文件夹内所有的文件并作整理统计
- android xml之Drawable 篇 --------shape和selector和layer-list的
- 使用Git提交项目到gitHub上
- hdu 1166
- hive+python数据分析入门
- FAQ系列 | 如何避免ibdata1文件大小暴涨
- Java提取两个文件夹中的有差异的文件并生成相应的shell脚本
- 方法的重载
- 排序问题-堆排序
- 如何在所有用户桌面上放一个快捷方式或者文件?
- iOS App Anatomy(解剖学) (UI 设计基础 二)
- Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable
- 关于运行String parentId = Util.createUUID()时报错InvocationTargetException的问题
- Drupal 中读取Excel数据再转换格式到另一个Excel
- 如何快速的读懂一个软件的源码