`

压缩包在内存中添加文件,并直接输出

 
阅读更多
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();
		}
	}
}
分享到:
评论

相关推荐

    一个内存流的合并添加删除读出输出的类(含DEMO)

    内存流在计算机编程中是一种非常重要的数据处理方式,特别是在Java、C#等编程语言中,它们提供了高效且灵活的数据操作接口。本主题聚焦于如何利用内存流进行数据的合并、添加、删除、读取和输出,同时附带了一个DEMO...

    dom4j解析xml文件的压缩包

    压缩包中的`dom4j-1.6.1.jar`文件包含了DOM4J库的类和资源,可以直接在Java项目中引入作为依赖,进行XML操作。为了使用这个库,你需要将该jar包添加到项目的类路径中,然后就可以通过DOM4J提供的类和方法来解析和...

    一个内存流的合并添加删除读出输出的类 (含DEMO)

    标题中的“一个内存流的合并添加删除读出输出的类 (含DEMO)”指的是一个用于处理内存流操作的自定义类,这个类可能包含了在内存中合并、添加、删除和读取输出数据流的功能。在Delphi编程环境中,内存流...

    java生成压缩包

    在这个包中,`ZipOutputStream`是生成ZIP文件的关键类,它可以让我们逐个添加文件到压缩包中。 生成ZIP文件的基本步骤如下: 1. **创建`ZipOutputStream`**:首先,我们需要一个输出流来写入ZIP数据。这通常涉及到...

    汇编-压缩包文件.rar

    5. **恢复记录**:RAR格式支持添加恢复记录,可以在文件损坏时帮助恢复数据。 6. **文件头**:包含文件信息,如文件名、压缩方法、时间戳等。 7. **压缩比**:衡量压缩效果的指标,高压缩比意味着更小的文件大小,...

    Android压缩包

    在Android平台上,压缩包的使用是非常常见的操作,无论是下载的应用程序、游戏,还是开发者们进行项目开发时的资源文件,都可能涉及到压缩和解压缩。本文将深入探讨Android中压缩包的处理,包括常见格式、使用工具...

    安卓Android源码——安卓Android 在线下载压缩包并解压到指定目录.rar

    可以通过监听`DownloadManager`的广播事件,或者直接在`OkHttp`的请求中添加回调来获取下载进度。 8. **错误处理**:在整个过程中,务必对可能出现的异常进行捕获和处理,例如网络错误、文件操作错误等。使用`try-...

    Qt内存溢出检测

    在你的压缩包文件`test_memoryLeak`中,可能包含了一个示例项目,用于演示如何在Qt应用中使用VLD进行内存溢出检测。你可以解压后编译运行,观察VLD如何帮助你定位内存问题。 总结来说,Qt内存溢出检测是保证程序...

    SDL图形支持库压缩包

    在压缩包文件“SDL_image-1.2.6”中,我们可以找到SDL_image库的版本1.2.6的源代码、编译文件、文档以及可能的示例程序。这个版本可能包含了头文件、库文件、配置脚本和其他必要的组件,供开发者在自己的项目中集成...

    cJson开源代码压缩包文件,可在C/C++项目中使用

    5. **线程安全**:虽然cJson库本身并不直接支持多线程,但开发者可以通过适当的同步机制确保在多线程环境中安全使用。 6. **错误处理**:cJson提供了错误检测机制,当解析JSON字符串出错时,可以捕获错误信息,帮助...

    Commons-io-2.16.2 压缩包

    在这个特定的压缩包"Commons-io-2.16.2"中,我们关注的是Apache Commons IO库的一个版本,虽然提供的文件名是"commons-io-2.16.1",但描述中提到的是2024.6.6的版本,可能是描述有误或者文件命名有误,我们暂时以...

    JSZip使用Javascript创建读取和编辑zip文件

    你可以逐个添加文件或直接添加整个目录结构。 - **读取ZIP文件**:JSZip可以从一个二进制字符串、ArrayBuffer或Blob中读取ZIP文件,并将其内容解析为可操作的对象。 - **编辑ZIP文件**:你可以选择性地修改ZIP文件...

    DELPHI BCB 程序中的报表输出到PDF控件

    在压缩包中的"llPdfLib_3.6"可能就是该库的一个版本,包含了头文件、库文件、示例代码等资源,供开发者参考和使用。通过研究这些文件,开发者可以更好地理解如何将llPDFLib集成到自己的项目中,实现报表到PDF的无缝...

    bmp-text.rar_vc 内存图片

    在提供的压缩包文件中,可以看到几个相关的示例项目,如“VC++ 图片加水印效果-在位图中输出文字字符串.rar”和“84097172ImageText.rar”。这些示例代码会演示如何实际操作上述步骤,为用户提供更直观的理解。 在...

    quazip(已编译好源码和库文件)可以直接使用

    在提供的压缩包中,您已经得到了预编译好的库文件和源码,这意味着您可以直接将它们集成到您的项目中,而无需自行编译。 首先,让我们深入了解一下Quazip库的关键特性: 1. **多平台支持**:Quazip是跨平台的,...

    大一原创C语言学生信息管理系统1.0项目源代码压缩包

    学生信息不可能始终存储在内存中,因此需要读写文件进行持久化存储。在C语言中,我们使用fopen、fwrite、fread和fclose等函数来完成文件的打开、写入、读取和关闭操作。项目可能有一个特定的文件用于存储学生数据,...

    成绩管理 包括4个文件 c语言

    在这个特定的压缩包文件中,我们看到它包含了4个C语言编写的源代码文件,这可能是用于实现一个简单的成绩管理系统的基础组件。 C语言是一种强大的、低级的编程语言,被广泛用于系统编程、嵌入式开发以及各种应用...

    内存泄露检测工具VLD(Visual Leak Detector)提取的头文件和库

    5. **编译和运行**:编译并运行程序,VLD会在控制台输出任何检测到的内存泄露。 VLD的一个重要优点是它可以自动关联内存分配到源代码的具体位置,使得定位问题更为直观。此外,由于VLD是动态加载的,因此不影响程序...

    完整版可执行动态载入&输出其他文件模块.rar

    这个“完整版可执行动态载入&输出其他文件模块.rar”压缩包很可能包含了一些示例代码或者库,用于演示如何在程序运行时动态地加载和使用外部模块,以及如何将数据或代码输出到其他文件中。下面我们将深入探讨这两个...

    给PE文件添加数字签名的代码

    标题中的“给PE文件添加数字签名的代码”指的是在Windows平台下,对Portable Executable (PE) 文件进行数字签名的过程。PE文件格式是Windows操作系统中用于执行程序的标准格式,包括.exe和.dll等类型。数字签名是...

Global site tag (gtag.js) - Google Analytics