怎么把app解压缩app成nds文件?

iOS中使用ZipArchive压缩和解压缩文件
/thread-119-1-1.html
在本教程中,我将演示如何在iOS程序中压缩和解压缩文件。我们将使用一个叫做ZipArchive的第三方库来实现。尽管压缩和解压缩有许多其他的方案可选,但是我觉得ZipArchive库是最快捷、最简单的解决方案。let’s
为什么我需要解压缩文件
有许多原因能解释为什么我要在工程中使用压缩和解压缩功能,下面是几个常见的原因:
苹果App Store的50M下载限制
果公司出于流量的考虑,规定在非WIFI环境下,限制用户只能下载小于50M的应用或游戏。这样一来,对于一些数据或数据包较大的应用,我们只能尽量减小
应用二进制包的体积。而把数据打包到zip中,这样App可以通过网络下载数据包,解压出所需要的内容,而且这样也可以动态的更新内容。
动态更新内容
一点在上面已经提过了。如果应用所需要的资源需要动态更新,一种常见的做法是更新资源,重新打包,重新提交到App
store,这样做你需要等待漫长的审核、上架时间。一般情况下是一周左右的时间。更好的方法是将这些资源打包放置在服务器上,App从服务器(或者云存
储)上下载,然后解压。这样做的好处显而易见,那就是可以快速更新,动态更新,不需要重新打包、上传、审核,省时省力。
从Web上下载zip文件
Safari和邮件程序都不支持zip的查看,通过ZipArchive你就可以为你的设备增加查看zip文件的能力了,尽管App
Store里已经有一些App支持这些功能了。
首先从google code上check
out一份代码,svn地址是:
在终端中输入如下命令即可check
或者直接从下载。
把minizip文件夹和ZipArchive.h以及ZipArchive.mm文件添加到你的工程中。
因为ZipArchive不支持ARC,所以如果你的工程开启了ARC,那么就需要对ZipArchive设置一下。在ZipArchive.mm编译选项中,增加-fno-objc-arc即可。
最后,需要为工程链接libz动态链接库。
至此,ZipArchive已经集成到你的工程中了,编译工程,应该可以编译成功。可能会有一些警告,这无关紧要,不影响编译。但是作为一个态度严谨的程序员,我强烈建议你看一下这些警告是怎么出现的,解决它们。请记住:在你的工程中,警告应该和错误一样被严肃处理!
下载和解压缩文件
下来就向大家展示在你的工程中如何从网上下载zip文件,解压缩,并读取zip压缩包中的文件内容。处于演示考虑,主要的目的是向大家演示
ZipArchive接口的使用方法,所以代码的错误处理和条件检查并没有做过多的考量,在实际的工程中,还是需要大家自己做更为严格的条件检查和错误处
示例工程的运行效果如下图:
程中只是在ViewController中增加了一个UIImageView和一个UILabel。我们将从网络上下载zip文件,zip文件中包含一张
图片和一个文本文件。下载解压后,图像会被渲染到UIImageView中,而文本会作为UILabel的内容展示。示例代码在文章末尾。希望读者朋友们
自行下载,编译,查看效果。
好,接下来讲一讲具体的实现:
1.引入ZipArchive的头文件。
#import "ZipArchive.h"
2.下载zip文件
& & dispatch_queue_t queue =
dispatch_get_global_queue(
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
& & dispatch_async(queue,
&&&NSURL *url =
URLWithString:@"/wp-content/uploads/2012/08/zipfile.zip"];
&&&NSError
&&&NSData *data
= [NSData dataWithContentsOfURL:url options:0
error:&error];
&&&if(!error)
&& &NSArray
*paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
&& &NSString
*path = [paths objectAtIndex:0];
&& &NSString
*zipPath = [path
stringByAppendingPathComponent:@"zipfile.zip"];
writeToFile:zipPath options:0 error:&error];
&if(!error)
&& & // TODO:
NSLog(@"Error saving file %@",error);
&NSLog(@"Error downloading zip file: %@",
上面这段代码的主要作用就是从iCodeBlog上下载一个zip文件,并写入到应用的缓存目录中。
现在zip文件已经下载下来了,接下来就是要解压缩,并将解压缩出来的文件利用起来。
3. 解压缩已下载的zip文件
在第二步中,我们已经把zip文件下载到/Library/Caches/zipfile.zip,现在来解压缩。
把上面代码中的//TODO:
Unzip用下面的代码替换掉。
ZipArchive *za = [[ZipArchive alloc] init];
if ([za UnzipOpenFile: zipPath]) {&
& & BOOL ret = [za
UnzipFileTo: path overWrite: YES];
& & if (NO == ret){} [za
UnzipCloseFile];
& & NSString *imageFilePath =
[path stringByAppendingPathComponent:@"photo.png"];
& & NSString *textFilePath =
[path stringByAppendingPathComponent:@"text.txt"];
& & NSData *imageData =
[NSData dataWithContentsOfFile:imageFilePath options:0
error:nil];
& & UIImage *img = [UIImage
imageWithData:imageData];
& & NSString *textString =
[NSString stringWithContentsOfFile:textFilePath
&&&encoding:NSASCIIStringEncoding
error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
&&&self.imageView.image
&&&self.label.text
对上面的代码做一个简单的解释:
1. 在内存中解压缩文件
2. 将解压缩的内容写到缓存目录中
3. 使用解压缩后的文件
非常简单吧!
接下来看一下怎么进行文件压缩。在上面的步骤中,我们已经把一个zip文件解压缩到缓存目录中。现在我们再把解压缩出来的文件重新压缩为一个zip文件,并把这个zip文件写入到Documents目录里去(OMG,这两个文件太惨了,被反复蹂躏)
在示例工程代码中,我已经增加了一个按钮,并和一个IBAction相关联,按钮的处理函数名为zipFilesBUttonPressed:,具体代码如下:
- (IBAction)zipFilesButtonPressed:(id)sender
& & NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
& & NSString *docspath =
[paths objectAtIndex:0];
& & paths =
NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
& & NSString *cachePath =
[paths objectAtIndex:0];
& & NSString *zipFile =
stringByAppendingPathComponent:@"newzipfile.zip"];&
& & ZipArchive *za =
[[ZipArchive alloc] init];
CreateZipFile2:zipFile];
& & NSString *imagePath =
[cachePath stringByAppendingPathComponent:@"photo.png"];
& & NSString *textPath =
[cachePath stringByAppendingPathComponent:@"text.txt"];
addFileToZip:imagePath newname:@"NewPhotoName.png"];
& & [za addFileToZip:textPath
newname:@"NewTextName.txt"];
& & BOOL success = [za
CloseZipFile2];& &
& & NSLog(@"Zipped file with
result %d",success);
简单解释一下上面代码的意思:
获取Documents目录,新的zip文件要写入到这个目录里。
获取Caches目录,要进行压缩的文件在这个目录里。
3. 获取zip文件的全路径名。
创建一个ZipArchive实例,并创建一个内存中的zip文件。需要注意的是,只有当你调用了CloseZipFile2方法之后,zip文件才会从内存中写入到磁盘中去。
5. 获取要被压缩的文件的全路径
把要压缩的文件加入到zip对象中去,加入的文件数量没有限制,也可以加入文件夹到zip对象中去。
把zip从内存中写入到磁盘中去。
当点击按钮之后,在应用的Documents文件夹下应该有一个叫newzipfile.zip的文件。解压这个文件,就能解压出那两个被反复蹂躏的文件来
现在你知道如何使用ZipArchive来压缩和解压缩文件了。享受ZipArchive的便利吧。示例工程已经很好的展示了这些基本用法,大家可以好好研究下。
示例工程: (179.4 KB)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。1528人阅读
Android(48)
& & & &记得上次在南昌中兴的一个项目中遇到过一个这样的需求:一个app可以给多个渠道商去运营,渠道商推广出去可以获得相应的推广金额。那么这种情况下就必须要使得这个app能够唯一的标志一个渠道商。那个时候我们在这个项目中的解决方案是:让用户在app中手动填入渠道商的工号,我现在想想这种方式也是醉了,真不知道那个时候项目经理是怎么想的,竟然会给出这样的方案。
这次的项目中又遇到了这个问题:需求是这个app能够给多个渠道商去推广,渠道商可以获得推广金额。这次我提出的解决方案是:先把打包后的app解压,然后在assets目录中写入渠道商的唯一标识id,然后压缩app,压缩完毕重新签名app,之后就大工告成。用户在第一次进入app的时候,会把assets中的id读出来,提交到服务器,就完美的解决了这个用户是此渠道商的推广所获得的用户。
首先第一步:把app解压,删除META-INF文件夹中的CERT.RSA和CERT.SF两个文件
第二步:读取解压后的assets目录中的id.txt文件,写入渠道商的id
&span style=&white-space:pre&&
&/span&File file = new File(&d:/app/assets/id.txt&);
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(user.getId().toString().getBytes());
outputStream.flush();
outputStream.close(); 第三步:压缩写入渠道商id后的所有app文件
&span style=&white-space:pre&&
&/span&ZipCompressor zc = new
ZipCompressor(&d:/play.apk&);
zc.compressExe(&d:/app/&); 具体的压缩代码如下:
package com.xyc.signSystem.
import java.io.BufferedInputS
import java.io.F
import java.io.FileInputS
import java.io.FileOutputS
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputS
import org.apache.tools.zip.ZipE
import org.apache.tools.zip.ZipOutputS
* @ClassName: ZipCompressor
* @author :andywuchuanlong
* @Description: 压缩文件的通用工具类-采用org.apache.tools.zip.ZipOutputStream实现,较复杂。
public class ZipCompressor {
static final int BUFFER = 8192;
private File zipF
* 压缩文件构造函数
* @param pathName
压缩的文件存放目录
public ZipCompressor(String pathName) {
zipFile = new File(pathName);
* 执行压缩操作
* @param srcPathName
被压缩的文件/文件夹
public void compressExe(String srcPathName) {
File file = new File(srcPathName);
if (!file.exists()) {
throw new RuntimeException(srcPathName + &不存在!&);
FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
new CRC32());
ZipOutputStream out = new ZipOutputStream(cos);
String basedir = &&;
compressByType(file, out, basedir);
out.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
* 判断是目录还是文件,根据类型(文件/文件夹)执行不同的压缩方法
* @param file
* @param out
* @param basedir
private void compressByType(File file, ZipOutputStream out, String basedir) {
if (basedir.equals(&play/&)) {
basedir = &&;
/* 判断是目录还是文件 */
if (file.isDirectory()) {
pressDirectory(file, out, basedir);
pressFile(file, out, basedir);
boolean isFirst =
* 压缩一个目录
* @param dir
* @param out
* @param basedir
private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
if (!dir.exists()) {
if (basedir.equals(&play/&)) {
basedir = &&;
File[] files = dir.listFiles();
for (int i = 0; i & files. i++) {
/* 递归 */
compressByType(files[i], out, basedir + dir.getName() + &/&);
* 压缩一个文件
* @param file
* @param out
* @param basedir
private void compressFile(File file, ZipOutputStream out, String basedir) {
if (!file.exists()) {
if (basedir.equals(&play/&)) {
basedir = &&;
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(file));
ZipEntry entry = new ZipEntry(basedir + file.getName());
out.putNextEntry(entry);
byte data[] = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
bis.close();
} catch (Exception e) {
throw new RuntimeException(e);
第四步:压缩完毕之后,此时的包是没有签名过的,所以还需要签名,签名可以使用jarsigner工具,首先我们要寻找到java的安装目录
&span style=&white-space:pre&& &/span&public
String getJavaPath() {
String javaPath = (String) System.getenv(&Path&);
String paths[]= javaPath.split(&;&);
String myPath =
for(String path:paths){
if (path.contains(&Java&)&&!path.contains(&jre&)
&&path.contains(&bin&) ){
return myPath+&\\&;
&span style=&white-space:pre&& &/span&String javaPath = getJavaPath();
Runtime rt = Runtime.getRuntime();
String cmd = javaPath
+ &jarsigner -verbose&
+ & -keystore &+ keystorePath
+ & -storepass player&// 密码
+ & -signedjar &+signedApkPath // 签名后的apk存放位置
+ & -digestalg SHA1
MD5withRSA &
+ unsignedApkPath//未签名的apk
+ & player&;// 别名
Process child = rt.exec(cmd);
OK,签名成功。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:236840次
积分:2926
积分:2926
排名:第9717名
原创:99篇
评论:139条
阅读:15610
文章:11篇
阅读:149735
(2)(1)(1)(1)(2)(2)(1)(4)(5)(2)(8)(5)(1)(18)(4)(7)(2)(5)(2)(30)(2)}

我要回帖

更多关于 app压缩 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信