读取WEB-INF/classes目录下文件,及读取其key-value

本文介绍了一个Java类,用于从类路径中加载配置文件并将其内容转换为Properties对象。该类首先尝试加载名为xiu-ui.properties的文件,如果未找到,则会尝试备选路径。加载成功后,可以通过方法获取配置项的值。

package com.ui.version.config;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Config {

private static Logger log = Logger.getLogger(Config.class.getName());

private static final String fileName = "xiu-ui.properties";
private static final String fileName2 = "com/ui/version/resources/xiu-ui.properties";


private static Properties properties = new Properties();;

static{
boolean ready = false;
InputStream is = Config.class.getClassLoader().getResourceAsStream(fileName);
if(is != null){
try {
properties.load(is);
ready = true;
log.log(Level.INFO, "加载classpath:"+fileName+"成功!");
} catch (IOException e) {
log.log(Level.WARNING, "加载classpath:"+fileName+"失败", e);
}
}
if(!ready){
is = Config.class.getClassLoader().getResourceAsStream(fileName2);
if(is != null){
try {
properties.load(is);
ready = true;
log.log(Level.INFO, "加载classpath:"+fileName2+"成功!");
} catch (IOException e) {
log.log(Level.WARNING, "加载classpath:"+fileName2+"失败", e);
}
}
}
if(!ready){
log.log(Level.SEVERE, "未能找到资源,请将"+fileName+"文件放到classes目录下");
}
}

public static String getConfigValue(String key){
return properties.getProperty(key,null);
}

public static Properties getProperties(){
return properties;
}

}

Microsoft Windows [版本 10.0.19045.6456] (c) Microsoft Corporation。保留所有权利。 C:\Users\Administrator>D:\test\spzx-manager\target\ 'D:\test\spzx-manager\target\' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 C:\Users\Administrator>cd /d "D:\新建文件夹 (4)\spzx-parent\spzx-manager\target" D:\新建文件夹 (4)\spzx-parent\spzx-manager\target>jar -tf spzx-manager-1.0-SNAPSHOT.jar | findstr BOOT-INF BOOT-INF/ BOOT-INF/classes/ BOOT-INF/classes/com/ BOOT-INF/classes/com/atgui/ BOOT-INF/classes/com/atgui/spzx/ BOOT-INF/classes/com/atgui/spzx/manager/ BOOT-INF/classes/com/atgui/spzx/manager/config/ BOOT-INF/classes/com/atgui/spzx/manager/controller/ BOOT-INF/classes/com/atgui/spzx/manager/helper/ BOOT-INF/classes/com/atgui/spzx/manager/interceptor/ BOOT-INF/classes/com/atgui/spzx/manager/listener/ BOOT-INF/classes/com/atgui/spzx/manager/mapper/ BOOT-INF/classes/com/atgui/spzx/manager/properties/ BOOT-INF/classes/com/atgui/spzx/manager/service/ BOOT-INF/classes/com/atgui/spzx/manager/service/impl/ BOOT-INF/classes/com/atgui/spzx/manager/task/ BOOT-INF/classes/mapper/ BOOT-INF/classes/mapper/user/ BOOT-INF/classes/application-dev.yml.bak BOOT-INF/classes/application.yml BOOT-INF/classes/com/atgui/spzx/manager/config/WebMvcConfiguration.class BOOT-INF/classes/com/atgui/spzx/manager/controller/BrandController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/CategoryBrandController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/CategoryController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/FileUploadController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/IndexController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/OrderInfoController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/ProductController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/ProductSpecController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/ProductUnitController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/SysMenuController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/SysRoleController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/SysRoleMenuController.class BOOT-INF/classes/com/atgui/spzx/manager/controller/SysUserController.class BOOT-INF/classes/com/atgui/spzx/manager/helper/MenuHelper.class BOOT-INF/classes/com/atgui/spzx/manager/interceptor/LoginAuthInterceptor.class BOOT-INF/classes/com/atgui/spzx/manager/listener/ExcelListener.class BOOT-INF/classes/com/atgui/spzx/manager/ManagerApplication.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/BrandMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/CategoryBrandMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/CategoryMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/OrderInfoMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/OrderStatisticsMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/ProductDetailsMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/ProductMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/ProductSkuMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/ProductSpecMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/ProductUnitMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/SysMenuMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/SysOperLogMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/SysRoleMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/SysRoleMenuMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/SysRoleUserMapper.class BOOT-INF/classes/com/atgui/spzx/manager/mapper/SysUserMapper.class BOOT-INF/classes/com/atgui/spzx/manager/properties/MinioProperties.class BOOT-INF/classes/com/atgui/spzx/manager/properties/UserAuthProperties.class BOOT-INF/classes/com/atgui/spzx/manager/service/BrandService.class BOOT-INF/classes/com/atgui/spzx/manager/service/CategoryBrandService.class BOOT-INF/classes/com/atgui/spzx/manager/service/CategoryService.class BOOT-INF/classes/com/atgui/spzx/manager/service/FileUploadService.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/AsyncOperLogServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/BrandServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/CategoryBrandServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/CategoryServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/FileUploadServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/OrderInfoServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/ProductServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/ProductSpecServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/ProductUnitServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/SysMenuServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/SysRoleMenuServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/SysRoleServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/SysUserServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/impl/ValidateCodeServiceImpl.class BOOT-INF/classes/com/atgui/spzx/manager/service/OrderInfoService.class BOOT-INF/classes/com/atgui/spzx/manager/service/ProductService.class BOOT-INF/classes/com/atgui/spzx/manager/service/ProductSpecService.class BOOT-INF/classes/com/atgui/spzx/manager/service/ProductUnitService.class BOOT-INF/classes/com/atgui/spzx/manager/service/SysMenuService.class BOOT-INF/classes/com/atgui/spzx/manager/service/SysRoleMenuService.class BOOT-INF/classes/com/atgui/spzx/manager/service/SysRoleService.class BOOT-INF/classes/com/atgui/spzx/manager/service/SysUserService.class BOOT-INF/classes/com/atgui/spzx/manager/service/ValidateCodeService.class BOOT-INF/classes/com/atgui/spzx/manager/task/OrderStatisticsTask.class BOOT-INF/classes/logback-spring.xml BOOT-INF/classes/mapper/user/BrandMapper.xml BOOT-INF/classes/mapper/user/CategoryBrandMapper.xml BOOT-INF/classes/mapper/user/CategoryMapper.xml BOOT-INF/classes/mapper/user/OrderInfoMapper.xml BOOT-INF/classes/mapper/user/OrderStatisticsMapper.xml BOOT-INF/classes/mapper/user/ProductDetailsMapper.xml BOOT-INF/classes/mapper/user/ProductMapper.xml BOOT-INF/classes/mapper/user/ProductSkuMapper.xml BOOT-INF/classes/mapper/user/ProductSpecMapper.xml BOOT-INF/classes/mapper/user/ProductUnitMapper.xml BOOT-INF/classes/mapper/user/SysMenuMapper.xml BOOT-INF/classes/mapper/user/SysOperLogMapper.xml BOOT-INF/classes/mapper/user/SysRoleMapper.xml BOOT-INF/classes/mapper/user/SysRoleMenuMapper.xml BOOT-INF/classes/mapper/user/SysRoleUserMapper.xml BOOT-INF/classes/mapper/user/SysUserMapper.xml BOOT-INF/classes/mybatis-config.xml BOOT-INF/lib/ BOOT-INF/lib/spring-boot-3.0.5.jar BOOT-INF/lib/spring-boot-autoconfigure-3.0.5.jar BOOT-INF/lib/logback-classic-1.4.6.jar BOOT-INF/lib/logback-core-1.4.6.jar BOOT-INF/lib/log4j-to-slf4j-2.19.0.jar BOOT-INF/lib/log4j-api-2.19.0.jar BOOT-INF/lib/jul-to-slf4j-2.0.7.jar BOOT-INF/lib/snakeyaml-1.33.jar BOOT-INF/lib/jackson-databind-2.14.2.jar BOOT-INF/lib/jackson-annotations-2.14.2.jar BOOT-INF/lib/jackson-datatype-jdk8-2.14.2.jar BOOT-INF/lib/jackson-datatype-jsr310-2.14.2.jar BOOT-INF/lib/jackson-module-parameter-names-2.14.2.jar BOOT-INF/lib/tomcat-embed-core-10.1.7.jar BOOT-INF/lib/tomcat-embed-el-10.1.7.jar BOOT-INF/lib/tomcat-embed-websocket-10.1.7.jar BOOT-INF/lib/spring-web-6.0.7.jar BOOT-INF/lib/spring-beans-6.0.7.jar BOOT-INF/lib/micrometer-observation-1.10.5.jar BOOT-INF/lib/micrometer-commons-1.10.5.jar BOOT-INF/lib/spring-webmvc-6.0.7.jar BOOT-INF/lib/spring-aop-6.0.7.jar BOOT-INF/lib/spring-context-6.0.7.jar BOOT-INF/lib/spring-expression-6.0.7.jar BOOT-INF/lib/spring-data-redis-3.0.4.jar BOOT-INF/lib/spring-data-keyvalue-3.0.4.jar BOOT-INF/lib/spring-data-commons-3.0.4.jar BOOT-INF/lib/spring-tx-6.0.7.jar BOOT-INF/lib/spring-oxm-6.0.7.jar BOOT-INF/lib/spring-context-support-6.0.7.jar BOOT-INF/lib/lettuce-core-6.2.3.RELEASE.jar BOOT-INF/lib/netty-common-4.1.90.Final.jar BOOT-INF/lib/netty-handler-4.1.90.Final.jar BOOT-INF/lib/netty-resolver-4.1.90.Final.jar BOOT-INF/lib/netty-buffer-4.1.90.Final.jar BOOT-INF/lib/netty-transport-native-unix-common-4.1.90.Final.jar BOOT-INF/lib/netty-codec-4.1.90.Final.jar BOOT-INF/lib/netty-transport-4.1.90.Final.jar BOOT-INF/lib/reactor-core-3.5.4.jar BOOT-INF/lib/reactive-streams-1.0.4.jar BOOT-INF/lib/mybatis-spring-boot-starter-3.0.1.jar BOOT-INF/lib/HikariCP-5.0.1.jar BOOT-INF/lib/spring-jdbc-6.0.7.jar BOOT-INF/lib/mybatis-spring-boot-autoconfigure-3.0.1.jar BOOT-INF/lib/mybatis-3.5.11.jar BOOT-INF/lib/mybatis-spring-3.0.1.jar BOOT-INF/lib/mysql-connector-j-8.0.32.jar BOOT-INF/lib/common-service-1.0-SNAPSHOT.jar BOOT-INF/lib/common-util-1.0-SNAPSHOT.jar BOOT-INF/lib/fastjson-2.0.21.jar BOOT-INF/lib/fastjson2-extension-2.0.21.jar BOOT-INF/lib/fastjson2-2.0.21.jar BOOT-INF/lib/minio-8.5.2.jar BOOT-INF/lib/simple-xml-safe-2.7.1.jar BOOT-INF/lib/guava-30.1.1-jre.jar BOOT-INF/lib/failureaccess-1.0.1.jar BOOT-INF/lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar BOOT-INF/lib/jsr305-3.0.2.jar BOOT-INF/lib/checker-qual-3.8.0.jar BOOT-INF/lib/error_prone_annotations-2.5.1.jar BOOT-INF/lib/j2objc-annotations-1.3.jar BOOT-INF/lib/okhttp-4.10.0.jar BOOT-INF/lib/okio-jvm-3.0.0.jar BOOT-INF/lib/kotlin-stdlib-jdk8-1.7.22.jar BOOT-INF/lib/kotlin-stdlib-jdk7-1.7.22.jar BOOT-INF/lib/kotlin-stdlib-common-1.7.22.jar BOOT-INF/lib/kotlin-stdlib-1.7.22.jar BOOT-INF/lib/annotations-13.0.jar BOOT-INF/lib/bcprov-jdk15on-1.69.jar BOOT-INF/lib/commons-compress-1.21.jar BOOT-INF/lib/snappy-java-1.1.8.4.jar BOOT-INF/lib/spzx-model-1.0-SNAPSHOT.jar BOOT-INF/lib/lombok-1.18.20.jar BOOT-INF/lib/knife4j-openapi3-jakarta-spring-boot-starter-4.1.0.jar BOOT-INF/lib/knife4j-core-4.1.0.jar BOOT-INF/lib/knife4j-openapi3-ui-4.1.0.jar BOOT-INF/lib/springdoc-openapi-starter-common-2.0.4.jar BOOT-INF/lib/swagger-core-jakarta-2.2.8.jar BOOT-INF/lib/commons-lang3-3.12.0.jar BOOT-INF/lib/jakarta.validation-api-3.0.2.jar BOOT-INF/lib/jackson-dataformat-yaml-2.14.2.jar BOOT-INF/lib/springdoc-openapi-starter-webflux-ui-2.0.4.jar BOOT-INF/lib/springdoc-openapi-starter-webflux-api-2.0.4.jar BOOT-INF/lib/spring-webflux-6.0.7.jar BOOT-INF/lib/swagger-ui-4.18.1.jar BOOT-INF/lib/webjars-locator-core-0.52.jar BOOT-INF/lib/classgraph-4.8.149.jar BOOT-INF/lib/springdoc-openapi-starter-webmvc-ui-2.0.4.jar BOOT-INF/lib/springdoc-openapi-starter-webmvc-api-2.0.4.jar BOOT-INF/lib/swagger-annotations-jakarta-2.2.8.jar BOOT-INF/lib/swagger-models-jakarta-2.2.8.jar BOOT-INF/lib/easyexcel-3.1.0.jar BOOT-INF/lib/easyexcel-core-3.1.0.jar BOOT-INF/lib/easyexcel-support-3.1.0.jar BOOT-INF/lib/poi-4.1.2.jar BOOT-INF/lib/commons-collections4-4.4.jar BOOT-INF/lib/commons-math3-3.6.1.jar BOOT-INF/lib/SparseBitSet-1.2.jar BOOT-INF/lib/poi-ooxml-4.1.2.jar BOOT-INF/lib/curvesapi-1.06.jar BOOT-INF/lib/poi-ooxml-schemas-4.1.2.jar BOOT-INF/lib/xmlbeans-3.1.0.jar BOOT-INF/lib/commons-csv-1.8.jar BOOT-INF/lib/ehcache-3.9.9.jar BOOT-INF/lib/byte-buddy-1.12.23.jar BOOT-INF/lib/hutool-all-5.5.2.jar BOOT-INF/lib/spring-boot-test-3.0.5.jar BOOT-INF/lib/spring-boot-test-autoconfigure-3.0.5.jar BOOT-INF/lib/json-path-2.7.0.jar BOOT-INF/lib/json-smart-2.4.10.jar BOOT-INF/lib/accessors-smart-2.4.9.jar BOOT-INF/lib/asm-9.3.jar BOOT-INF/lib/jakarta.xml.bind-api-4.0.0.jar BOOT-INF/lib/jakarta.activation-api-2.1.1.jar BOOT-INF/lib/assertj-core-3.23.1.jar BOOT-INF/lib/hamcrest-2.2.jar BOOT-INF/lib/junit-jupiter-5.9.2.jar BOOT-INF/lib/junit-jupiter-api-5.9.2.jar BOOT-INF/lib/opentest4j-1.2.0.jar BOOT-INF/lib/junit-platform-commons-1.9.2.jar BOOT-INF/lib/apiguardian-api-1.1.2.jar BOOT-INF/lib/junit-jupiter-params-5.9.2.jar BOOT-INF/lib/junit-jupiter-engine-5.9.2.jar BOOT-INF/lib/junit-platform-engine-1.9.2.jar BOOT-INF/lib/mockito-core-4.8.1.jar BOOT-INF/lib/byte-buddy-agent-1.12.23.jar BOOT-INF/lib/objenesis-3.2.jar BOOT-INF/lib/mockito-junit-jupiter-4.8.1.jar BOOT-INF/lib/jsonassert-1.5.1.jar BOOT-INF/lib/android-json-0.0.20131108.vaadin1.jar BOOT-INF/lib/spring-core-6.0.7.jar BOOT-INF/lib/spring-jcl-6.0.7.jar BOOT-INF/lib/spring-test-6.0.7.jar BOOT-INF/lib/xmlunit-core-2.9.1.jar BOOT-INF/lib/pagehelper-spring-boot-starter-1.4.3.jar BOOT-INF/lib/pagehelper-spring-boot-autoconfigure-1.4.3.jar BOOT-INF/lib/pagehelper-5.3.1.jar BOOT-INF/lib/jsqlparser-4.2.jar BOOT-INF/lib/common-log-1.0-SNAPSHOT.jar BOOT-INF/lib/aspectjweaver-1.9.19.jar BOOT-INF/lib/spring-cloud-starter-alibaba-nacos-discovery-2022.0.0.0-RC2.jar BOOT-INF/lib/spring-cloud-alibaba-commons-2022.0.0.0-RC2.jar BOOT-INF/lib/nacos-client-2.2.1.jar BOOT-INF/lib/nacos-auth-plugin-2.2.1.jar BOOT-INF/lib/nacos-encryption-plugin-2.2.1.jar BOOT-INF/lib/commons-codec-1.15.jar BOOT-INF/lib/jackson-core-2.14.2.jar BOOT-INF/lib/httpasyncclient-4.1.5.jar BOOT-INF/lib/httpcore-4.4.16.jar BOOT-INF/lib/httpcore-nio-4.4.16.jar BOOT-INF/lib/httpclient-4.5.14.jar BOOT-INF/lib/simpleclient-0.16.0.jar BOOT-INF/lib/simpleclient_tracer_otel-0.16.0.jar BOOT-INF/lib/simpleclient_tracer_common-0.16.0.jar BOOT-INF/lib/simpleclient_tracer_otel_agent-0.16.0.jar BOOT-INF/lib/spring-context-support-1.0.11.jar BOOT-INF/lib/spring-cloud-commons-4.0.2.jar BOOT-INF/lib/spring-security-crypto-6.0.2.jar BOOT-INF/lib/spring-cloud-context-4.0.2.jar BOOT-INF/lib/spring-cloud-starter-alibaba-sentinel-2022.0.0.0-RC2.jar BOOT-INF/lib/sentinel-transport-simple-http-1.8.6.jar BOOT-INF/lib/sentinel-transport-common-1.8.6.jar BOOT-INF/lib/sentinel-datasource-extension-1.8.6.jar BOOT-INF/lib/sentinel-annotation-aspectj-1.8.6.jar BOOT-INF/lib/sentinel-core-1.8.6.jar BOOT-INF/lib/spring-cloud-circuitbreaker-sentinel-2022.0.0.0-RC2.jar BOOT-INF/lib/sentinel-reactor-adapter-1.8.6.jar BOOT-INF/lib/sentinel-spring-webflux-adapter-1.8.6.jar BOOT-INF/lib/sentinel-spring-webmvc-6x-adapter-1.8.6.jar BOOT-INF/lib/sentinel-parameter-flow-control-1.8.6.jar BOOT-INF/lib/concurrentlinkedhashmap-lru-1.4.2.jar BOOT-INF/lib/sentinel-cluster-server-default-1.8.6.jar BOOT-INF/lib/sentinel-cluster-common-default-1.8.6.jar BOOT-INF/lib/sentinel-cluster-client-default-1.8.6.jar BOOT-INF/lib/spring-cloud-alibaba-sentinel-datasource-2022.0.0.0-RC2.jar BOOT-INF/lib/spring-cloud-starter-alibaba-nacos-config-2022.0.0.0-RC2.jar BOOT-INF/lib/slf4j-api-2.0.7.jar BOOT-INF/lib/jakarta.annotation-api-2.1.1.jar BOOT-INF/lib/spring-boot-jarmode-layertools-3.0.5.jar BOOT-INF/classpath.idx BOOT-INF/layers.idx D:\新建文件夹 (4)\spzx-parent\spzx-manager\target>
最新发布
11-12
请将这份kotlin代码转换成java代码,保留原有功能和注释内容。要转换的kotlin代码:【package kim.hsl.multiple_dex_tools import java.io.* import java.util.zip.* /** * 此处配置 SDK 根目录绝对路径 * D:/001_Programs/001_Android/002_Sdk/Sdk/ * Y:/001_DevelopTools/002_Android_SDK/ */ val sdkDirectory = "Y:/001_DevelopTools/002_Android_SDK/" @ExperimentalStdlibApi fun main() { /* 1 . 生成 dex 文件 , 该 dex 文件中只包含解密 其它 dex 的功能 编译工程 会生成 Android 依赖库的 aar 文件 生成目录是 module/build/outputs/aar/ 目录下 前提是需要在 菜单栏 / File / Setting / Build, Execution, Deployment / Compiler 设置界面中 , 勾选 Compile independent modules in parallel (may require larger ) 将 D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-core\build\outputs\aar 路径下的 multiple-dex-core-debug.aar 文件后缀修改为 .zip 解压上述文件 拿到 classes.jar 文件即可 ; */ // 获取 multiple-dex-core-debug.aar 文件对象 var aarFile = File("multiple-dex-core/build/outputs/aar/multiple-dex-core-debug.aar") // 解压上述 multiple-dex-core-debug.aar 文件到 aarUnzip 目录中 // 创建解压目录 var aarUnzip = File("multiple-dex-tools/aarUnzip") // 解压操作 unZip(aarFile, aarUnzip) // 拿到 multiple-dex-core-debug.aar 中解压出来的 classes.jar 文件 var classesJarFile = File(aarUnzip, "classes.jar") // 创建转换后的 dex 目的文件, 下面会开始创建该 dex 文件 var classesDexFile = File(aarUnzip, "classes.dex") // 打印要执行的命令 println("cmd /c ${sdkDirectory}build-tools/30.0.2/dx.bat --dex --output ${classesDexFile.absolutePath} ${classesJarFile.absolutePath}") /* 将 jar 包变成 dex 文件 使用 dx 工具命令 注意 : Windows 命令行命令之前需要加上 "cmd /c " 信息 , Linux 与 MAC 命令行不用添加 */ var process = Runtime.getRuntime().exec("cmd /c ${sdkDirectory}build-tools/30.0.2/dx.bat --dex --output ${classesDexFile.absolutePath} ${classesJarFile.absolutePath}") // 等待上述命令执行完毕 process.waitFor() // 执行结果提示 if(process.exitValue() == 0){ println("生成 dex 操作 , 执行成功"); } else { println("生成 dex 操作 , 执行失败"); } /* 2 . 加密 apk 中的 dex 文件 */ // 解压 apk 文件 , 获取所有的 dex 文件 // 被解压的 apk 文件 var apkFile = File("app/build/outputs/apk/debug/app-debug.apk") // 解压的目标文件夹 var apkUnZipFile = File("app/build/outputs/apk/debug/unZipFile") // 解压文件 unZip(apkFile, apkUnZipFile) // 从被解压的 apk 文件中找到所有的 dex 文件, 小项目只有 1 个, 大项目可能有多个 // 使用文件过滤器获取后缀是 .dex 的文件 var dexFiles : Array<File> = apkUnZipFile.listFiles({ file: File, s: String -> s.endsWith(".dex") }) // 加密找到的 dex 文件 var aes = AES(AES.DEFAULT_PWD) // 遍历 dex 文件 for(dexFile: File in dexFiles){ // 读取文件数据 var bytes = getBytes(dexFile) // 加密文件数据 var encryptedBytes = aes.encrypt(bytes) // 将加密后的数据写出到指定目录 var outputFile = File(apkUnZipFile, "secret-${dexFile.name}") // 创建对应输出流 var fileOutputStream = FileOutputStream(outputFile) // 将加密后的 dex 文件写出, 然后刷写 , 关闭该输出流 fileOutputStream.write(encryptedBytes) fileOutputStream.flush() fileOutputStream.close() // 删除原来的文件 dexFile.delete() } /* 3 . 将代理 Application 中的 classes.dex 解压到上述 app/build/outputs/apk/debug/unZipFile 目录中 */ // 拷贝文件到 app/build/outputs/apk/debug/unZipFile 目录classesDexFile.renameTo(File(apkUnZipFile, "classes.dex")) // 压缩打包 , 该压缩包是未签名的压缩包 var unSignedApk = File("app/build/outputs/apk/debug/app-unsigned.apk") // 压缩打包操作 zip(apkUnZipFile, unSignedApk) /* 4 . 对齐操作 */ // 对齐操作的输出结果, 将 app-unsigned.apk 对齐, 对齐后的文件输出到 app-unsigned-aligned.apk 中 var unSignedAlignApk = File("app/build/outputs/apk/debug/app-unsigned-aligned.apk") // 打印要执行的命令 println("cmd /c ${sdkDirectory}build-tools/30.0.2/zipalign -f 4 ${unSignedApk.absolutePath} ${unSignedAlignApk.absolutePath}") /* 将 app-unsigned.apk 对齐 使用 zipalign 工具命令 注意 : Windows 命令行命令之前需要加上 "cmd /c " 信息 , Linux 与 MAC 命令行不用添加 */ process = Runtime.getRuntime().exec("cmd /c ${sdkDirectory}build-tools/30.0.2/zipalign -f 4 ${unSignedApk.absolutePath} ${unSignedAlignApk.absolutePath}") // 等待上述命令执行完毕 process.waitFor() // 执行结果提示 if(process.exitValue() == 0){ println("对齐操作 执行成功"); } else { println("对齐操作 执行失败"); } /* 5 . 签名操作 */ // 签名 apk 输出结果, 将 app-unsigned-aligned.apk 签名, 签名后的文件输出到 app-signed-aligned.apk 中 var signedAlignApk = File("app/build/outputs/apk/debug/app-signed-aligned.apk") // 获取签名 jks 文件 var jksFile = File("dex.jks") // 打印要执行的命令 println("cmd /c ${sdkDirectory}build-tools/30.0.2/apksigner sign --ks ${jksFile.absolutePath} --ks-key-alias Key0 --ks-pass pass:000000 --key-pass pass:000000 --out ${signedAlignApk.absolutePath} ${unSignedAlignApk.absolutePath}") /* 将 app-unsigned.apk 对齐 使用 zipalign 工具命令 注意 : Windows 命令行命令之前需要加上 "cmd /c " 信息 , Linux 与 MAC 命令行不用添加 */ process = Runtime.getRuntime().exec("cmd /c ${sdkDirectory}build-tools/30.0.2/apksigner sign --ks ${jksFile.absolutePath} --ks-key-alias Key0 --ks-pass pass:000000 --key-pass pass:000000 --out ${signedAlignApk.absolutePath} ${unSignedAlignApk.absolutePath}") // 打印错误日志 var br = BufferedReader(InputStreamReader(process.errorStream)) while ( true ){ var line = br.readLine() if(line == null){ break }else{ println(line) } } br.close() // 等待上述命令执行完毕 process.waitFor() // 执行结果提示 if(process.exitValue() == 0){ println("签名操作 执行成功"); } else { println("签名操作 执行失败"); } } /** * 删除文件, 如果有目录, 则递归删除 */ private fun deleteFile(file: File) { if (file.isDirectory) { val files = file.listFiles() for (f in files) { deleteFile(f) } } else { file.delete() } } /** * 解压文件 * @param zip 被解压的压缩包文件 * @param dir 解压后的文件存放目录 */ fun unZip(zip: File, dir: File) { try { // 如果存放文件目录存在, 删除该目录 deleteFile(dir) // 获取 zip 压缩包文件 val zipFile = ZipFile(zip) // 获取 zip 压缩包中每一个文件条目 val entries = zipFile.entries() // 遍历压缩包中的文件 while (entries.hasMoreElements()) { val zipEntry = entries.nextElement() // zip 压缩包中的文件名称 或 目录名称 val name = zipEntry.name // 如果 apk 压缩包中含有以下文件 , 这些文件是 V1 签名文件保存目录 , 不需要解压 , 跳过即可 if (name == "META-INF/CERT.RSA" || name == "META-INF/CERT.SF" || (name == "META-INF/MANIFEST.MF") ) { continue } // 如果该文件条目 , 不是目录 , 说明就是文件 if (!zipEntry.isDirectory) { val file = File(dir, name) // 创建目录 if (!file.parentFile.exists()) { file.parentFile.mkdirs() } // 向刚才创建的目录中写出文件 val fileOutputStream = FileOutputStream(file) val inputStream = zipFile.getInputStream(zipEntry) val buffer = ByteArray(1024) var len: Int while (inputStream.read(buffer).also { len = it } != -1) { fileOutputStream.write(buffer, 0, len) } inputStream.close() fileOutputStream.close() } } // 关闭 zip 文件 zipFile.close() } catch (e: Exception) { e.printStackTrace() } } fun zip(dir: File, zip: File) { // 如果目标压缩包存在 , 删除该压缩包 zip.delete() // 对输出文件做 CRC32 校验 val cos = CheckedOutputStream(FileOutputStream( zip), CRC32()) val zos = ZipOutputStream(cos) // 压缩文件 compress(dir, zos, "") zos.flush() zos.close() } private fun compress(srcFile: File, zos: ZipOutputStream, basePath: String) { if (srcFile.isDirectory) { val files = srcFile.listFiles() for (file in files) { // zip 递归添加目录中的文件 compress(file, zos, basePath + srcFile.name + "/") } } else { compressFile(srcFile, zos, basePath) } } private fun compressFile(file: File, zos: ZipOutputStream, dir: String) { // 拼接完整的文件路径名称 val fullName = dir + file.name // app/build/outputs/apk/debug/unZipFile 路径 val fileNames = fullName.split("/").toTypedArray() // 正确的文件目录名 val sb = StringBuffer() if (fileNames.size > 1) { for (i in 1 until fileNames.size) { sb.append("/") sb.append(fileNames[i]) } } else { sb.append("/") } // 添加 zip 条目 val entry = ZipEntry(sb.substring(1)) zos.putNextEntry(entry) // 读取 zip 条目输出到文件中 val fis = FileInputStream(file) var len: Int val data = ByteArray(2048) while (fis.read(data, 0, 2048).also { len = it } != -1) { zos.write(data, 0, len) } fis.close() zos.closeEntry() } /** * 读取文件到数组中 */ fun getBytes(file: File): ByteArray { // 创建随机方位文件对象 val randomAccessFile = RandomAccessFile(file, "r") // 获取文件大小 , 并创建同样大小的数据组 val buffer = ByteArray(randomAccessFile.length().toInt()) // 读取真个文件到数组中 randomAccessFile.readFully(buffer) // 关闭文件 randomAccessFile.close() return buffer }】
08-26
课程名称: 大数据技术原理与应用 专业班级: 数科2304 姓 名: 仇一焯 学 号: 2023002253 指导教师: 陈泽华老师 2025年10月20日 实验 Spark Word Count 一 、实验内容: 基本要求: 完成Spark Word Count 二 、实验工具 虚拟机软件 VMware Workstation Pro17 操作系统 CentOS 7(64 位) ftp工具 XShell 8 Java 版本 jdk1.8.0_212 Hadoop 版本 hadoop-3.1.3 Spark版本 Spark 3.3.0 Maven 版本 Maven 3.6.3 三 、实验过程与截图 1.前置检查(必须执行) 1.1检查Spark集群状态 在 Master 节点(hadoop102)执行以下命令,确认 Master 和 Worker 进程正常运行: - 执行节点:在 HDFS 的主节点(通常是 `hadoop102`)上执行。 - 命令(绝对路径): /opt/module/hadoop-3.1.3/sbin/start-dfs.sh 验证:在所有节点上执行 `jps` 命令。 - `hadoop102` 应看到 `NameNode` 和 `DataNode`。 - `hadoop103` 应看到 `DataNode`。 - `hadoop104` 应看到 `DataNode` 和 `SecondaryNameNode` 一键启动集群(自动启动 Master 和所有 Worker): $SPARK_HOME/sbin/start-all.sh # 查看Master节点进程 Jps # 查看Worker节点进程(分别在hadoop103、hadoop104执行) Jps 解释:jps命令用于查看 Java 进程,需确保 hadoop102 有Master进程,hadoop103/104 有Worker进程,否则需重启集群:$SPARK_HOME/sbin/start-all.sh。 1.2验证HDFS服务可用性 词频统计需通过 HDFS 存储输入输出数据,执行以下命令检查 HDFS 状态: # 查看HDFS根目录 hdfs dfs -ls / # 测试HDFS写入权限 hdfs dfs -touchz /test.txt && hdfs dfs -rm /test.txt 解释:通过创建临时文件验证 HDFS 读写权限,若提示`Permission denied`需检查 Hadoop 目录权限配置。 2. 数据准备(HDFS 数据上传) 2.1 创建 HDFS 数据目录 # 创建输入目录(存放待分析文本) hdfs dfs -mkdir -p /spark-wordcount/input # 创建输出目录(后续运行前需删除,此处仅为演示) hdfs dfs -mkdir -p /spark-wordcount/output 2.2 准备本地测试文本 vi /home/atguigu/wordcount-data.txt 粘贴测试内容: Hello Spark Hello Hadoop Spark is fast Hadoop is stable Hello Spark HBase Spark Spark Spark 2.3上传文本到 HDFS hdfs dfs -put /home/atguigu/wordcount-data.txt /spark-wordcount/input/ # 验证上传结果 hdfs dfs -ls /spark-wordcount/input/ 3. 词频统计实现(Scala 语言方案) 3.1编写 Scala 代码 1. 创建代码目录(含 Maven 要求的源码结构) # 创建项目根目录 mkdir -p /home/atguigu/spark-code/scala # 进入项目根目录 cd /home/atguigu/spark-code/scala # 创建 Maven 规定的 Scala 源码目录(必须!否则 Maven 找不到代码) mkdir -p src/main/scala 2. 在正确目录下编写代码 # 注意:代码必须放在 src/main/scala 目录下 vi src/main/scala/WordCount.scala 3. 粘贴代码 // 导入Spark核心依赖(必须完整,避免编译错误) import org.apache.spark.{SparkConf, SparkContext} // 词频统计主类(单例对象,Scala中可作为入口类,类名必须与pom.xml的mainClass一致) object WordCount { def main(args: Array[String]): Unit = { // 1. 配置Spark应用(集群模式下,setMaster可通过spark-submit参数覆盖,更灵活) val conf = new SparkConf() .setAppName("Scala-WordCount") // 应用名称,Web UI可见 // 注:集群提交时建议删除setMaster,通过--master参数指定,避免硬编码 // .setMaster("spark://192.168.10.102:7077") .set("spark.executor.memory", "2g") .set("spark.cores.max", "4") // 2. 创建Spark上下文(核心入口,需确保配置正确) val sc = new SparkContext(conf) sc.setLogLevel("WARN") // 减少日志输出,聚焦结果 // 3. 处理输入输出路径(优先使用命令行参数,适配不同场景) val inputPath = if (args.length > 0) args(0) else "/spark-wordcount/input" val outputPath = if (args.length > 1) args(1) else "/spark-wordcount/output" // 4. 核心逻辑(分步注释,清晰易懂) val wordCounts = sc.textFile(inputPath) // 读取文件:每行作为一个元素 .flatMap(line => line.split("\\s+")) // 分词:按任意空白分割,扁平化为单词 .map(word => (word, 1)) // 标记计数:每个单词映射为(单词, 1) .reduceByKey(_ + _) // 聚合:按单词累加计数(简化写法,等价于(a,b)=>a+b) .sortBy(_._2, ascending = false) // 排序:按词频降序 // 5. 输出结果(控制台+HDFS,双重验证) println("=== 词频统计结果 ===") wordCounts.collect().foreach(println) // 控制台打印(仅适合小数据) wordCounts.saveAsTextFile(outputPath) // 保存到HDFS(分布式场景推荐) // 6. 释放资源(必须执行,避免内存泄漏) sc.stop() } } \- `textFile`:读取 HDFS 或本地文件,返回行级 RDD(弹性分布式数据集),是 Spark 数据处理的基础结构; `flatMap`:扁平化转换,将每行文本拆分为单个单词,解决`map`操作可能产生的嵌套数组问题; `reduceByKey`:Spark 核心聚合算子,自动按 key 分组并执行累加,比`groupByKey`更高效(减少网络传输); `collect`:动作算子,将分布式 RDD 数据拉取到 Driver 节点,仅适合小结果集查看。 4. 验证代码位置(关键检查): # 确保代码在 src/main/scala 目录下 ls -l src/main/scala/WordCount.scala # 预期输出:-rw-r--r-- 1 atguigu atguigu ... src/main/scala/WordCount.scala 3.2 打包 Scala 代码(Maven 方式) 1.创建 `pom.xml`: vi /home/atguigu/spark-code/scala/pom.xml 复制粘贴以下配置(适配 Spark 3.3.0 和 Scala 2.12) <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 项目基本信息(自定义,确保唯一即可) --> <groupId>com.atguigu.spark</groupId> <artifactId>spark-wordcount</artifactId> <version>1.0-SNAPSHOT</version> <!-- 版本管理(关键:Scala与Spark版本必须匹配) --> <properties> <scala.version>2.12.15</scala.version> <!-- Spark 3.3.0适配Scala 2.12.x --> <spark.version>3.3.0</spark.version> <!-- 与集群Spark版本一致 --> <maven.compiler.source>1.8</maven.compiler.source> <!-- 适配JDK 1.8 --> <maven.compiler.target>1.8</maven.compiler.target> </properties> <!-- 依赖配置(仅包含必要依赖,避免冲突) --> <dependencies> <!-- Spark核心依赖(scope=provided:集群已存在,打包不包含) --> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.12</artifactId> <!-- 后缀_2.12对应Scala版本 --> <version>${spark.version}</version> <scope>provided</scope> </dependency> </dependencies> <!-- 构建配置(核心:确保Scala代码编译并打包进JAR) --> <build> <sourceDirectory>src/main/scala</sourceDirectory> <!-- 指定Scala源码目录 --> <testSourceDirectory>src/main/test</testSourceDirectory> <plugins> <!-- 1. Scala编译插件(必须配置,否则Maven无法编译.scala文件--> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>4.5.4</version> <executions> <execution> <id>scala-compile</id> <goals> <goal>compile</goal> <!-- 编译Scala源码 --> <goal>testCompile</goal> </goals> <configuration> <args> <arg>-dependencyfile</arg> <arg>${project.build.directory}/.scala_dependencies</arg> </args> </configuration> </execution> </executions> </plugin> <!-- 2. 打包插件(生成可执行JAR,包含主类信息) --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>package</phase> <goals><goal>shade</goal></goals> <configuration> <!-- 解决依赖冲突:保留最后一个依赖版本 --> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <!-- 指定主类(必须与Scala代码中的object名称一致) --> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>WordCount</mainClass> <!-- 无包名时直接写类名 --> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> 编译并打包: # 进入项目根目录 cd /home/atguigu/spark-code/scala # 清理旧文件并编译(首次编译时间较长) mvn clean scala:compile # 【关键验证1】检查是否生成 .class 文件 ls -l target/classes/WordCount.class # 若输出 ".class" 文件,说明编译成功;否则检查代码语法或目录 # 打包 mvn package 3.3 提交任务到 Spark 集群 1. 上传 JAR 到 HDFS: hdfs dfs -put -f target/spark-wordcount-1.0-SNAPSHOT.jar /spark-jars/ 2. 删除旧输出目录(避免冲突): hdfs dfs -rm -r /spark-wordcount/output 3. 提交任务: $SPARK_HOME/bin/spark-submit \ --master spark://192.168.10.102:7077 \ --class WordCount \ hdfs://192.168.10.102:8020/spark-jars/spark-wordcount-1.0-SNAPSHOT.jar \ /spark-wordcount/input \ /spark-wordcount/output 4. 问题:版本过低需要升级 解决步骤:升级 Maven 到 3.3.9 及以上版本 步骤 1:查看当前 Maven 版本(确认问题) 执行以下命令,查看当前 Maven 版本: mvn -v 如果输出的`Maven home`对应的版本低于`3.3.9`(例如`3.0.5`),则需要升级。 步骤 2:下载并安装兼容的 Maven 版本 推荐安装Maven 3.6.3(兼容 3.3.9 + 要求,且稳定): 1. 进入临时目录下载安装包: cd /tmp wget http://maven.aliyun.com/nexus/content/groups/public/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.tar.gz 2. 解压到`/opt/module`目录(与你的其他软件目录统一): sudo tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /opt/module/ 3. 重命名目录(方便后续配置): sudo mv /opt/module/apache-maven-3.6.3 /opt/module/maven-3.6.3 4. 配置环境变量(替换旧版本 Maven):编辑`/etc/profile`文件: sudo vi /etc/profile 添加以下内容(分别在hadoop102.103.104上进行配置)(确保覆盖系统默认的 Maven 路径): export MAVEN_HOME=/opt/module/maven-3.6.3 export PATH=$MAVEN_HOME/bin:$PATH 生效配置: source /etc/profile 步骤 3:验证 Maven 版本是否升级成功 再次执行: mvn -v 若输出类似以下内容,说明升级成功: ```plaintext Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /opt/module/maven-3.6.3 Java version: 1.8.0_212, vendor: Oracle Corporation, runtime: /opt/module/jdk1.8.0_212/jre 根据以上内容,生成流程图,一共四部分分别是总体介绍,详细操作,问题解决和总结与讨论
10-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值