由于好玩,本人写了一个增加打包程序,读者都知道,增量打包时,需要把修改的文件挑选出来,并按目录创建好,如果修改的文件还较少,还可以忍受,如果修改的文件超过一定量,那么确实是一件令人无聊,重复的工作。所以本人就写了一个增量打包程序,根据文件的最后修改时间提取修改的class文件,配置文件,属性文件等,并在根目录生成一个自述文件,记录提取的文件,以便核对,现在发布出来,希望能帮到你,配置文件Extract.properties,读者根据可以项目相关的情况修改。暂不支持内部类,如果有次需要,请自己修改程序。
PackgaeUtil类:
public class PackgaeUtil {
private Logger logger = Logger.getLogger(this.getClass());
private static final String EXTRACT_HOUR = "extract.hour";
private static final String EXTRACT_ITEM_DIR = "extract.item.dir";
private static final String EXTRACT_ITEM_PARENT = "extract.item.parent";
private static final String EXTRACT_SOURCE_PATH = "extract.source.path";
private static final String EXTRACT_SRC_PATH = "extract.src.path";
private static final String EXTRACT_CLASS_PATH = "extract.class.path";
private static final String EXTRACT_PACKAGE_PATH = "extract.package.dir";
private Config config = Config.getInstance();
private List<String> readmeList = new ArrayList<String>();
public static void main(String[] args) throws Exception {
PackgaeUtil packageUtil = new PackgaeUtil();
packageUtil.action();
}
/**
*
*/
private void action() {
boolean parent = Boolean.valueOf(config
.getProperty(EXTRACT_ITEM_PARENT));
File itemDir = new File(config.getProperty(EXTRACT_ITEM_DIR));
if (parent) {
File[] itemFiles = itemDir.listFiles(new ItemDirectoryFilter());
for (int i = 0; i < itemFiles.length; i++) {
// 提取需要打包的文件
extractPackageFiles(itemFiles[i]);
}
} else {
extractPackageFiles(itemDir);
}
writeReadmeFile();// 记录自述文件
}
/**
* 记录提取的文件至自述文件
*/
private void writeReadmeFile() {
String readmeFile = getPackagedDirectory() + File.separator
+ "readme.txt";
try {
Collections.sort(readmeList);
FileUtils.writeLines(new File(readmeFile), readmeList);
} catch (IOException e) {
logger.error(e.getMessage(),e);
}
}
/**
* 提取指定时间内被修改的文件,包括类文件,资源,配置文件,另外还有JSP,FTL文件
*
* @param itemFile
*/
private void extractPackageFiles(File itemFile) {
try {
File sourceFileDir = new File(itemFile.getAbsoluteFile()
+ File.separator + config.getProperty(EXTRACT_SOURCE_PATH));
List<String> sourceFilenameList = new ArrayList<String>();
String hour = config.getProperty(EXTRACT_HOUR);
getChangeSourceFile(sourceFilenameList, sourceFileDir, Integer
.valueOf(hour));
sourceFilenameList = getNeedPackageClassFile(sourceFilenameList);
packageSourceFile(itemFile.getName(), sourceFilenameList);
} catch (Exception e) {
logger.error(e.getMessage(),e);
}
}
/**
* 打包源文件,包括类文件,资源,配置文件,另外还有JSP,FTL文件
*
* @param itemName
* @param sourceFilenameList
* @throws IOException
*/
private void packageSourceFile(String itemName,
List<String> sourceFilenameList) throws IOException {
if (sourceFilenameList.size() == 0) {
return;
}
String rootDir = getPackagedDirectory() + File.separator + itemName;
for (String sourceFilename : sourceFilenameList) {
String replaceStr = "";
if (sourceFilename.endsWith(".class")) {
replaceStr = "/target".replace("/", File.separator);
} else {
replaceStr = config.getProperty(EXTRACT_SOURCE_PATH).replace(
"/", File.separator);
}
int beginIndex = sourceFilename.indexOf(replaceStr)
+ replaceStr.length();
String destFile = rootDir + sourceFilename.substring(beginIndex);
readmeList.add(sourceFilename.substring(beginIndex));
createDestDirectory(destFile);
FileUtils.copyFile(new File(sourceFilename), new File(destFile));
}
}
/**
* 获取打包路径
*
* @param itemName
* @return
*/
private String getPackagedDirectory() {
StringBuffer packagedDir = new StringBuffer();
packagedDir.append(config.getProperty(EXTRACT_PACKAGE_PATH));
packagedDir.append(File.separator);
packagedDir.append(new File(config.getProperty(EXTRACT_ITEM_DIR))
.getName());
return packagedDir.toString().replace("/", File.separator);
}
/**
* 创建目标目录
*
* @param destFile
*/
private void createDestDirectory(String destFile) {
File destDir = new File(destFile).getParentFile();
if (!destDir.exists()) {
destDir.mkdirs();
}
}
/**
* 获取需要打包的类文件
*
* @param sourceFilenameList
* @return
*/
private List<String> getNeedPackageClassFile(List<String> sourceFilenameList) {
String sourceDir = config.getProperty(EXTRACT_SRC_PATH).replace("/",
File.separator);
String classDir = config.getProperty(EXTRACT_CLASS_PATH).replace("/",
File.separator);
List<String> classFilenameList = new ArrayList<String>();
for (String sourceFilename : sourceFilenameList) {
// 只有JAVA文件,才替换成class路径
if (sourceFilename.endsWith(".java")) {
// TODO 还解决内部类的问题
String classFileName = sourceFilename.replace(sourceDir,
classDir).replace(".java", ".class");
classFilenameList.add(classFileName);
continue;
}
classFilenameList.add(sourceFilename);
}
return classFilenameList;
}
/**
* 获取在指定时间之内发生变更的源文件
*
* @param sourceFilenameList
* @param sourceFileDir
* @param changeHours
* @throws IOException
*/
private void getChangeSourceFile(List<String> sourceFilenameList,
File sourceFileDir, int changeHours) throws IOException {
File[] sourceFiles = sourceFileDir.listFiles();
for (int i = 0; i < sourceFiles.length; i++) {
File sourceFile = sourceFiles[i];
// 如果是目录,递归寻找文件
if (sourceFile.isDirectory()) {
getChangeSourceFile(sourceFilenameList, sourceFile, changeHours);
}
long lastModified = sourceFile.lastModified();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(lastModified);
cal.add(Calendar.HOUR_OF_DAY, changeHours);
// 是否是文件,且最后修改日期是否在指定范围之内
if (sourceFile.isFile() && cal.getTime().after(new Date())) {
sourceFilenameList.add(sourceFile.getCanonicalPath());
}
}
}
private class ItemDirectoryFilter implements java.io.FileFilter {
@Override
public boolean accept(File pathname) {
if (!pathname.isDirectory()) {
return false;
}
if (pathname.getName().startsWith(".")) {
return false;
}
return true;
}
}
}
Config类:
public class Config {
private Logger logger = Logger.getLogger(this.getClass());
private Map<String, String> configs = new HashMap<String, String>();
private static Config config;
private Config() {
initConfig();
}
public static Config getInstance() {
if (config == null) {
config = new Config();
}
return config;
}
@SuppressWarnings("unchecked")
public void initConfig() {
Properties pro = new Properties();
try {
pro
.load(this.getClass().getResourceAsStream(
"/extract.properties"));
logger.debug("load extract.properties...");
Enumeration keys = pro.keys();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
String value = (String) pro.get(key);
logger.debug(key + ":" + value);
configs.put(key, (String) pro.get(key));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
} catch (IOException e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
}
}
public String getProperty(String key) {
String value = configs.get(key);
if (StringUtils.isEmpty(value)) {
return "";
}
return value;
}
}
属性文件extract.properties:
#提取多少小时内修改的文件
extract.hour = 30
#提取的项目目录
extract.item.dir = d:/work/mallplatform
#指定的项目目录是否是一个父项目
extract.item.parent = true
#源文件,资源文件,配置文件相对项目的路径
extract.source.path = /src/main
#java文件相对项目的路径
extract.src.path = /src/main/java
#class文件相对项目的路径
extract.class.path = /target/classes
#打包的路径
extract.package.dir = d:/package
maven依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
</dependency>
分享到:
相关推荐
"JAVA增量包打包工具"就是针对这一需求而设计的专业桌面应用程序,旨在帮助开发者实现自动化、高效的Web项目增量打包和发布。这款工具支持多种版本控制系统,包括Gitee(国内的Git托管平台)、Git和SVN,为多模块...
增量打包工具patch-generator-desk-v2.0.0是一款针对IT项目,特别是Web应用程序的高效自动化打包解决方案。这款工具旨在简化版本更新过程,通过只打包自上次发布以来更改过的文件,显著减少部署包的大小,从而提高...
【svn增量打包小工具】是一种基于Java开发的实用程序,专为IT专业人士设计,用于高效地管理和打包在Subversion(svn)版本控制系统中的代码更改。这个小工具的主要目的是简化版本控制过程,特别是在处理大型项目时,...
本"java增量升级程序.zip"文件主要是基于Subversion(SVN)版本控制系统来实现的增量打包。SVN是一个开源的版本控制系统,用于跟踪项目文件的历史变更,便于团队协作和代码管理。在这个过程中,我们首先需要确保本地...
4. **构建工具集成**:增量打包可能与Maven或Gradle等构建工具相结合,自动化处理更新打包过程。 5. **源码分析**:文章可能包含解析Java源码和字节码以识别变动的方法,或者利用编译器API来获取修改信息。 6. **...
增量打包工具是软件开发过程中非常实用的一种工具,它主要用于提高软件发布和更新的效率。在传统的打包过程中,每次发布新版本都需要将整个项目的所有文件重新打包,这不仅消耗时间,而且在网络传输上也浪费了大量的...
公司内的WEB程序每次升级只允许增量升级,不允许全量升级,每次必须挨个目录找文件,太麻烦了,特此做了个打包程序,相信各位也有用得到的,有需要源代码的下载后给我发邮件即可 1. 选择项目位置,该项目位置为已...
增量打包意味着只打包自上次打包以来发生变化的文件,这样可以节省存储空间,提高效率。 描述中提到的“能抓取指定目录下的文件”,这是打包工具的基本功能之一。用户可以通过设定特定的路径,让工具扫描并收集该...
Java增量升级工具是一种高效、便捷的软件更新解决方案,主要用于Java应用程序的版本迭代和维护。它允许开发者仅上传和处理自上次版本以来发生更改的部分,而不是整个应用,从而大大减少了升级包的大小,提升了用户...
在Eclipse环境中完成一个Java应用程序后,对其进行打包发行是非常重要的一步。打包的过程不仅包括将项目中的所有类文件和其他资源压缩成一个易于分发的形式,还需要确保这些打包后的文件能够被正确地执行。 ##### ...
4. **客户端下载**:当用户检查更新时,客户端应用程序会从服务器下载这个较小的增量包,而不是整个新APK。 5. **本地应用更新**:客户端接收到增量包后,利用这个差异数据来更新本地的APK文件。这个过程可能涉及到...
增量更新jar包是一种在软件开发中常见的优化策略,它的目的是减少用户下载和安装新版本应用程序时的数据量,提高更新效率,降低服务器负载。在Java应用开发中,jar(Java Archive)包是常用的代码打包和分发格式。当...
【Ant脚本自动构建SVN增量】是一种高效且节省资源的软件开发实践,它使得开发和测试团队能够自动化处理从代码提交到构建、打包、再到部署的整个过程。使用Ant,一个基于XML的构建工具,可以创建可重复执行的脚本来...
增量更新(差分升级)是Android应用程序开发中的一个重要技术,它允许用户仅下载自上次版本以来发生更改的部分代码,而不是整个应用的新版本。这大大减少了更新所需的网络带宽,提高了用户体验,同时也减轻了服务器...
总结来说,这个JAVA ANT自动备份程序利用了ANT的强大功能,通过XML配置文件实现了灵活的备份策略,特别是增量备份,降低了资源消耗。用户只需按照提供的`使用说明.txt`进行操作,就可以定制和运行这个备份系统,有效...
本文将围绕“JAVA手机开发环境搭建”这一主题,详细阐述如何利用Eclipse及其插件EclipseME,结合必要的开发工具,构建起一套完整的JAVA手机应用程序开发环境。 #### Eclipse:核心开发平台 Eclipse是一个开源的、...
在Android开发中,为了提高用户体验和减少数据消耗,开发者经常采用增量升级的方式来更新应用程序。增量升级允许用户只下载和安装自上次版本以来发生变化的部分,而不是整个apk文件。本篇文章将聚焦于如何使用SO...
- **编译与运行**:本书提供了如何编译和运行第一个Java程序“Hello World”的示例,包括创建类、编写main方法、使用命令行工具javac进行编译以及使用java命令运行程序的具体步骤。 #### 第一课:入门 - **测试...
2. **打包增量包**:将差异部分打包成增量更新包,这个包只包含必要的修改,体积相对较小。 3. **下载与验证**:在用户设备上,应用检测到新版本后,下载增量包,并验证其完整性。 4. **应用增量包**:在本地解压...