import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ApkUtil {
private static final Logger logger = LoggerFactory.getLogger(ApkUtil.class);
private static final byte[] sourceApkBytes = initializeSourceApk();
private ApkUtil(){}
private static byte[] initializeSourceApk() {
String sourceApkPath = ApkUtil.class.getResource("/app/ZHXS.apk").getPath();
byte[] tmpBytes = new byte[1024];
File apkFile = new File(sourceApkPath);
ByteArrayOutputStream apkOut = new ByteArrayOutputStream();
FileInputStream apkFis = null;
try {
apkFis = new FileInputStream(apkFile);
int b = 0;
while ((b = apkFis.read(tmpBytes)) != -1) {
apkOut.write(tmpBytes, 0, b);
}
return apkOut.toByteArray();
} catch (Exception e) {
logger.error(e.getMessage() ,e);
} finally {
closeInputStream(apkFis);
closeOutputStream(apkOut);
}
return null;
}
private static void closeOutputStream(OutputStream outputStream) {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
private static void closeInputStream(InputStream inputStream) {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
public static byte[] addFilesToExistingZip(String fileName) throws IOException {
ByteArrayOutputStream finalByteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStrem = new ZipOutputStream(finalByteArrayOutputStream);
ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(sourceApkBytes));
ZipEntry entry = zipInputStream.getNextEntry();
byte[] buf = new byte[1024];
while (entry != null) {
String name = entry.getName();
zipOutputStrem.putNextEntry(new ZipEntry(name));
int len;
while ((len = zipInputStream.read(buf)) > 0) {
zipOutputStrem.write(buf, 0, len);
}
entry = zipInputStream.getNextEntry();
}
closeInputStream(zipInputStream);
if (StringUtils.isNotBlank(fileName)) {
zipOutputStrem.putNextEntry(new ZipEntry("META-INF/" + fileName));
}
zipOutputStrem.closeEntry();
closeOutputStream(zipOutputStrem);
return finalByteArrayOutputStream.toByteArray();
}
public static void downloadApk(String fileName, HttpServletResponse response) {
ServletOutputStream output = null;
try {
output = response.getOutputStream();
byte[] bytes = null;
if (StringUtils.isNotBlank(fileName)) {
bytes = addFilesToExistingZip(fileName);
} else {
bytes = sourceApkBytes;
}
output.write(bytes);
} catch (IOException e) {
logger.error("Failed to download" + fileName + "apk");
} finally {
closeOutputStream(output);
}
}
public static void main(String[] args) {
try {
byte[] bytes = addFilesToExistingZip("zhxs_2699_"+URLEncoder.encode("测试", "utf-8"));
String targetDir = ApkUtil.class.getResource("/app/").getPath();
// 输出
FileOutputStream outt = new FileOutputStream(new File(targetDir + "zhxs_2699.apk"));
outt.write(bytes);
outt.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
分享到:
相关推荐
内存流在计算机编程中是一种非常重要的数据处理方式,特别是在Java、C#等编程语言中,它们提供了高效且灵活的数据操作接口。本主题聚焦于如何利用内存流进行数据的合并、添加、删除、读取和输出,同时附带了一个DEMO...
压缩包中的`dom4j-1.6.1.jar`文件包含了DOM4J库的类和资源,可以直接在Java项目中引入作为依赖,进行XML操作。为了使用这个库,你需要将该jar包添加到项目的类路径中,然后就可以通过DOM4J提供的类和方法来解析和...
标题中的“一个内存流的合并添加删除读出输出的类 (含DEMO)”指的是一个用于处理内存流操作的自定义类,这个类可能包含了在内存中合并、添加、删除和读取输出数据流的功能。在Delphi编程环境中,内存流...
在这个包中,`ZipOutputStream`是生成ZIP文件的关键类,它可以让我们逐个添加文件到压缩包中。 生成ZIP文件的基本步骤如下: 1. **创建`ZipOutputStream`**:首先,我们需要一个输出流来写入ZIP数据。这通常涉及到...
5. **恢复记录**:RAR格式支持添加恢复记录,可以在文件损坏时帮助恢复数据。 6. **文件头**:包含文件信息,如文件名、压缩方法、时间戳等。 7. **压缩比**:衡量压缩效果的指标,高压缩比意味着更小的文件大小,...
在Android平台上,压缩包的使用是非常常见的操作,无论是下载的应用程序、游戏,还是开发者们进行项目开发时的资源文件,都可能涉及到压缩和解压缩。本文将深入探讨Android中压缩包的处理,包括常见格式、使用工具...
可以通过监听`DownloadManager`的广播事件,或者直接在`OkHttp`的请求中添加回调来获取下载进度。 8. **错误处理**:在整个过程中,务必对可能出现的异常进行捕获和处理,例如网络错误、文件操作错误等。使用`try-...
在你的压缩包文件`test_memoryLeak`中,可能包含了一个示例项目,用于演示如何在Qt应用中使用VLD进行内存溢出检测。你可以解压后编译运行,观察VLD如何帮助你定位内存问题。 总结来说,Qt内存溢出检测是保证程序...
在压缩包文件“SDL_image-1.2.6”中,我们可以找到SDL_image库的版本1.2.6的源代码、编译文件、文档以及可能的示例程序。这个版本可能包含了头文件、库文件、配置脚本和其他必要的组件,供开发者在自己的项目中集成...
5. **线程安全**:虽然cJson库本身并不直接支持多线程,但开发者可以通过适当的同步机制确保在多线程环境中安全使用。 6. **错误处理**:cJson提供了错误检测机制,当解析JSON字符串出错时,可以捕获错误信息,帮助...
在这个特定的压缩包"Commons-io-2.16.2"中,我们关注的是Apache Commons IO库的一个版本,虽然提供的文件名是"commons-io-2.16.1",但描述中提到的是2024.6.6的版本,可能是描述有误或者文件命名有误,我们暂时以...
你可以逐个添加文件或直接添加整个目录结构。 - **读取ZIP文件**:JSZip可以从一个二进制字符串、ArrayBuffer或Blob中读取ZIP文件,并将其内容解析为可操作的对象。 - **编辑ZIP文件**:你可以选择性地修改ZIP文件...
在压缩包中的"llPdfLib_3.6"可能就是该库的一个版本,包含了头文件、库文件、示例代码等资源,供开发者参考和使用。通过研究这些文件,开发者可以更好地理解如何将llPDFLib集成到自己的项目中,实现报表到PDF的无缝...
在提供的压缩包文件中,可以看到几个相关的示例项目,如“VC++ 图片加水印效果-在位图中输出文字字符串.rar”和“84097172ImageText.rar”。这些示例代码会演示如何实际操作上述步骤,为用户提供更直观的理解。 在...
在提供的压缩包中,您已经得到了预编译好的库文件和源码,这意味着您可以直接将它们集成到您的项目中,而无需自行编译。 首先,让我们深入了解一下Quazip库的关键特性: 1. **多平台支持**:Quazip是跨平台的,...
学生信息不可能始终存储在内存中,因此需要读写文件进行持久化存储。在C语言中,我们使用fopen、fwrite、fread和fclose等函数来完成文件的打开、写入、读取和关闭操作。项目可能有一个特定的文件用于存储学生数据,...
在这个特定的压缩包文件中,我们看到它包含了4个C语言编写的源代码文件,这可能是用于实现一个简单的成绩管理系统的基础组件。 C语言是一种强大的、低级的编程语言,被广泛用于系统编程、嵌入式开发以及各种应用...
5. **编译和运行**:编译并运行程序,VLD会在控制台输出任何检测到的内存泄露。 VLD的一个重要优点是它可以自动关联内存分配到源代码的具体位置,使得定位问题更为直观。此外,由于VLD是动态加载的,因此不影响程序...
这个“完整版可执行动态载入&输出其他文件模块.rar”压缩包很可能包含了一些示例代码或者库,用于演示如何在程序运行时动态地加载和使用外部模块,以及如何将数据或代码输出到其他文件中。下面我们将深入探讨这两个...
标题中的“给PE文件添加数字签名的代码”指的是在Windows平台下,对Portable Executable (PE) 文件进行数字签名的过程。PE文件格式是Windows操作系统中用于执行程序的标准格式,包括.exe和.dll等类型。数字签名是...