[zip]android下实现直接读取zip中的文件
来源:互联网 发布:谷歌网站seo教程 编辑:程序博客网 时间:2024/05/16 08:27
不用解压,直接读取zip中指定的文件,例如文件/sdcard/a.zip中有文件z.txt,读取步骤如下:
- int zfd = zip_open("/sdcard/a.zip/z.txt");
- if (ZIP_IS_VALID(zfd)) {
- zip_seek(zfd, 5, SEEK_SET);
- zip_read(zfd, buf, 10);
- zip_close(zfd);
- }
1.依赖于android framework中的ZipFileRO.h,要求在android系统源码环境中编译;
2.目前只支持以“存储“格式压缩的zip文件;
3.主要接口:
- int zip_open(const char* path);
- int zip_close(int handle);
- int zip_read(int handle, void *buf, int count);
- int zip_seek(int fd, int offset, int whence);
- int zip_stat(const char *file_name, struct stat *buf);
zip_wrapper.h
- /*
- * read a file in zip as normal file.
- * only support kCompressStored method
- *
- * dependent on android ZipFileRO.h
- * build in AOSP
- *
- * zip_open
- * zip_close
- * zip_read
- * zip_seek
- * zip_stat
- */
- #ifndef _ZIP_WRAPPER_H_
- #define _ZIP_WRAPPER_H_
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <android/log.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
- #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
- #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
- #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
- #define ZIP_IS_VALID(f) ((f) != 0)
- int zip_open(const char* path);
- int zip_close(int handle);
- int zip_read(int handle, void *buf, int count);
- int zip_seek(int fd, int offset, int whence);
- int zip_stat(const char *file_name, struct stat *buf);
- #ifdef __cplusplus
- }
- #endif
- #endif //#ifndef _ZIP_WRAPPER_H_
zip_wrapper.cpp
- #define LOG_TAG "zip_wrapper"
- #include <utils/ZipFileRO.h>
- #include "zip_wrapper.h"
- using namespace android;
- extern "C" {
- #define ZIP_FLAG ".zip/"
- #define ZIP_FLAG_LEN strlen(ZIP_FLAG)
- static int is_file(const char* path)
- {
- int ok = 0;
- struct stat buf;
- int ret = stat(path, &buf);
- if (ret == 0) {
- if (S_ISREG(buf.st_mode)) {
- ok = 1;//is file
- } else {
- //LOGI("%s is not a file !", path);
- }
- } else {
- LOGI("%s is not exist ! ret = %d", path, ret);
- }
- return ok;
- }
- static int is_dir(const char* path)
- {
- int ok = 0;
- struct stat buf;
- int ret = stat(path, &buf);
- if (ret == 0) {
- if (S_ISDIR(buf.st_mode)) {
- ok = 1;//is dir
- } else {
- //LOGI("%s is not a dir !", path);
- }
- } else {
- LOGI("%s is not exist !", path);
- }
- return ok;
- }
- static int get_zip_path(const char* path, char* zippath)
- {
- int ok = 0;
- const char* p = NULL;
- p = strstr(path, ZIP_FLAG);
- if (p && (p + ZIP_FLAG_LEN != path + strlen(path))) {
- if (zippath) {
- strncpy(zippath, path, p + ZIP_FLAG_LEN - 1 - path);
- LOGI("zip path: %s", zippath);
- } // else, just judge the path is ok
- ok = 1;
- }
- return ok;
- }
- static int get_path_in_zip(const char* path, char* pathinzip)
- {
- int ok = 0;
- const char* p = NULL;
- p = strstr(path, ZIP_FLAG);
- if (p && (p + ZIP_FLAG_LEN != path + strlen(path))) {
- if (pathinzip) {
- strcpy(pathinzip, p + ZIP_FLAG_LEN);
- //LOGI("path in zip: %s", pathinzip);
- } // else, just judge the path is ok
- ok = 1;
- }
- return ok;
- }
- // whether or not the file is in zip
- // /xxx/a.zip/b.txt return true if a.zip is a file, else false
- // /xxx/a.zip/ return false
- // /xxx/a.zip return false
- // /xxx/a.txt return false
- //
- int is_in_zip(const char* path)
- {
- int iszip = 0;
- struct stat buf;
- char zippath[PATH_MAX] = {0};
- if (path == NULL) {
- LOGE("is_in_zip() path is null !");
- return iszip;
- }
- int ret = stat(path, &buf);
- //LOGI("PATH_MAX = %d", PATH_MAX);
- LOGI("path: %s", path);
- if (ret < 0) { // failed, maybe /xxx/a.zip/b.txt or no exist
- if (get_zip_path(path, zippath)) {
- if (is_file(zippath)) {
- LOGI("%s is in zip: %s", path, zippath);
- iszip = 1; // OK
- } else {
- LOGI("%s is not a zip", zippath);
- }
- } else {
- LOGI("%s is not exist!", path);
- }
- } else {
- if (S_ISDIR(buf.st_mode)) {
- LOGI("%s is a dir", path);
- } else if (S_ISREG(buf.st_mode)) {
- LOGI("%s is a file", path);
- } else {
- LOGI("%s not a file or dir", path);
- }
- }
- return iszip;
- }
- /******************************************************************/
- typedef struct _zip_priv {
- ZipFileRO * zip;
- ZipEntryRO entry;
- FileMap * map;
- off_t offset;
- }zip_priv;
- static zip_priv * _zip_priv_open(const char * path)
- {
- char zippath[PATH_MAX] = {0};
- char filepath[256] = {0};
- get_zip_path(path, zippath);
- get_path_in_zip(path, filepath);
- int fd = 0;
- zip_priv * zp = NULL;
- ZipFileRO * zip = new ZipFileRO();
- ZipEntryRO entry = NULL;
- FileMap* map = NULL;
- do
- {
- if (zip->open(zippath) != NO_ERROR) {
- LOGE("zip->open(%s) failed!", zippath);
- break;
- }
- entry = zip->findEntryByName(filepath);
- if (entry == 0) {
- LOGE("zip->findEntryByName(%s) failed!", filepath);
- break;
- }
- int method = 0;
- if (!zip->getEntryInfo(entry, &method, 0, 0, 0, 0, 0)) {
- LOGE("zip->getEntryInfo() failed!");
- break;
- }
- // only support stored method
- if (method != ZipFileRO::kCompressStored) {
- LOGE("error: not support, method = %d !\n"
- "only support kCompressStored", method);
- break;
- }
- map = zip->createEntryFileMap(entry);
- if (map == 0) {
- LOGE("zip->createEntryFileMap(%p) failed!", entry);
- break;
- }
- zp = (zip_priv *)malloc(sizeof(zip_priv));
- if (zp == NULL) {
- LOGE("malloc(sizeof(zip_priv)) failed !");
- break;
- }
- memset(zp, 0, sizeof(zip_priv));
- zp->zip = zip;
- zp->entry = entry;
- zp->map = map;
- zp->offset = 0;
- fd = (int)zp; //ok
- }while(0);
- if (fd == 0) {
- if (map) map->release();
- if (zip) delete zip;
- if (zp) free(zp);
- LOGI("_zip_open(%s) failed !", path);
- } else {
- LOGI("_zip_open(%s) ok !", path);
- }
- return zp;
- }
- static int _zip_open(const char * path)
- {
- return (int)_zip_priv_open(path);
- }
- static int _zip_close(int handle)
- {
- int ret = -1;
- zip_priv * zp = (zip_priv*)handle;
- if (zp) {
- zp->map->release();
- delete zp->zip;
- free(zp);
- ret = 0;
- }
- return ret;
- }
- static ssize_t _zip_read(int handle, void *buf, size_t count)
- {
- int ret = -1;
- zip_priv * zp = (zip_priv*)handle;
- if (zp) {
- size_t max = zp->map->getDataLength() - zp->offset;
- max = max < count ? max : count;
- if (max > 0) {
- memcpy(buf, ((char *)zp->map->getDataPtr()) + zp->offset, max);
- zp->offset += max;
- }
- ret = max;
- }
- return ret;
- }
- static off_t _zip_seek(int handle, off_t offset, int whence)
- {
- int ret = -1;
- zip_priv * zp = (zip_priv*)handle;
- off_t _offset, datalen;
- if (zp) {
- _offset = zp->offset;
- datalen = zp->map->getDataLength();
- switch(whence) {
- case SEEK_SET:
- _offset = offset;
- break;
- case SEEK_CUR:
- _offset += offset;
- break;
- case SEEK_END:
- _offset = datalen + offset;
- break;
- default:
- LOGE("_zip_seek not support whence: %d", whence);
- break;
- }
- if (_offset != zp->offset) {
- _offset = _offset >= 0 ? _offset : 0;
- zp->offset = _offset <= datalen ? _offset : datalen;
- }
- ret = zp->offset;
- }
- return ret;
- }
- /*
- buf->st_size
- buf->st_mode & S_IFREG
- buf->st_mode & S_IFDIR
- buf->st_mtime
- */
- static int _zip_stat(const char *file_name, struct stat *buf)
- {
- int ret = -1;
- zip_priv * zp = _zip_priv_open(file_name);
- do
- {
- if (zp == NULL) {
- break;
- }
- memset(buf, 0, sizeof(struct stat));
- size_t uncompLen = 0;
- if (!zp->zip->getEntryInfo(zp->entry, 0, &uncompLen, 0, 0, 0, 0)) {
- LOGE("zp->zip->getEntryInfo() failed !");
- break;
- }
- LOGI("uncompLen = %d", uncompLen);
- buf->st_size = uncompLen;
- char name[256] = {0};
- if (zp->zip->getEntryFileName(zp->entry, name, sizeof(name)) == -1) {
- LOGE("zp->zip->getEntryFileName() failed !");
- break;
- }
- if (name[strlen(name) - 1] == '/') {
- buf->st_mode = S_IFDIR;
- LOGI("%s is a dir", name);
- } else {
- buf->st_mode = S_IFREG;
- LOGI("%s is a file", name);
- }
- buf->st_mtime = 0;
- ret = 0;
- }while(0);
- if (zp) {
- _zip_close((int)zp);
- }
- return ret;
- }
- /******************************************************************/
- typedef struct _fs_operator {
- int (*close)(int handle);
- ssize_t (*read) (int handle, void *buf, size_t count);
- off_t (*seek) (int handle, off_t offset, int whence);
- } fs_operator;
- typedef struct _zip_info {
- const fs_operator * opt;
- int fd;
- } zip_info;
- static const fs_operator s_operator[] =
- {
- {
- close,
- read,
- lseek,
- },
- {
- _zip_close,
- _zip_read,
- _zip_seek,
- },
- };
- /******************************************************************/
- // api
- int zip_open(const char* path)
- {
- int zfd = 0;
- zip_info * pz = NULL;
- if (path == NULL) {
- LOGE("zip_open: path is null");
- return -1;
- }
- do
- {
- pz = (zip_info *) malloc(sizeof(zip_info));
- if (pz == NULL) {
- LOGE("malloc(sizeof(zip_info)) failed !");
- break;
- }
- memset(pz, 0, sizeof(zip_info));
- int fd = 0;
- if (is_in_zip(path)) {
- fd = _zip_open(path);
- if (!fd) {
- break;
- }
- pz->opt = &s_operator[1];
- } else {
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- LOGE("open(%s) failed!", path);
- break;
- }
- pz->opt = &s_operator[0];
- }
- pz->fd = fd;
- zfd = (int)pz;
- }while(0);
- if (!ZIP_IS_VALID(zfd)) {
- if (pz) free(pz);
- }
- return zfd;
- }
- int zip_close(int handle)
- {
- int ret = -1;
- zip_info * pz = (zip_info *)handle;
- if (pz) {
- ret = pz->opt->close(pz->fd);
- <span style="white-space:pre"> </span>free(pz);
- }
- return ret;
- }
- int zip_read(int handle, void *buf, int count)
- {
- int ret = -1;
- zip_info * pz = (zip_info *)handle;
- if (pz) {
- ret = pz->opt->read(pz->fd, buf, count);
- }
- return ret;
- }
- int zip_seek(int handle, int offset, int whence)
- {
- int ret = -1;
- zip_info * pz = (zip_info *)handle;
- if (pz) {
- ret = pz->opt->seek(pz->fd, offset, whence);
- }
- return ret;
- }
- int zip_stat(const char *file_name, struct stat *buf)
- {
- int ret = -1;
- if(file_name && buf) {
- if (is_in_zip(file_name)) {
- ret = _zip_stat(file_name, buf);
- } else {
- ret = stat(file_name, buf);
- }
- } else {
- }
- return ret;
- }
- }//extern "C" {
zip_main.cpp
- #define LOG_TAG "zip_wrapper"
- #include <utils/String8.h>
- #include <utils/ZipFileRO.h>
- #include "zip_wrapper.h"
- using namespace android;
- extern "C" {
- int is_in_zip(const char* path);
- }
- // ---------------------------------------------------------------------------
- int testReadEntry(int argc, char** argv)
- {
- ZipFileRO mZip;
- char path[256] = "/sdcard/zip/demo.zip";
- if (argc >= 2) {
- strcpy(path, argv[1]);
- }
- LOGI("path: %s\n", path);
- mZip.open(path);
- size_t numEntries = mZip.getNumEntries();
- LOGI("numEntries: %d\n", numEntries);
- if ((int)numEntries < 0){
- return 0;
- }
- int method = 0;
- size_t uncompLen = 0;
- size_t compLen = 0;
- off64_t offset = 0;
- long modWhen = 0;
- long crc32 = 0;
- char name[256] = {0};
- for (size_t i=0 ; i<numEntries ; i++) {
- ZipEntryRO entry = mZip.findEntryByIndex(i);
- if (mZip.getEntryFileName(entry, name, sizeof(name)) == 0) {
- if (mZip.getEntryInfo(entry, &method, &uncompLen,
- &compLen, &offset, &modWhen, &crc32)) {
- LOGI("name:[%d] %s\n", i, name);
- LOGI("method: %d\n", method);
- LOGI("uncompLen: %d,\tcompLen: %d\n", uncompLen, compLen);
- LOGI("offset: %lld,\tcrc32: 0x%lx\n", offset, crc32);
- }
- }
- }
- return 0;
- }
- int testIsInZip(int argc, char** argv)
- {
- if (argc < 2) {
- LOGE("parameter is error! :%s filepath", argv[0]);
- return -1;
- }
- return is_in_zip(argv[1]);
- }
- int testRead(int argc, char** argv)
- {
- int zfd = 0;
- char buf[100] = {0};
- if (argc < 2) {
- LOGE("parameter is error! :%s filepath", argv[0]);
- return -1;
- }
- zfd = zip_open(argv[1]);
- LOGI("zfd = 0x%x", zfd);
- if (ZIP_IS_VALID(zfd)) {
- zip_read(zfd, buf, 10);
- LOGI("read: %s", buf);
- memset(buf, 0, sizeof(buf));
- zip_seek(zfd, 5, SEEK_SET);
- zip_read(zfd, buf, 10);
- LOGI("read: %s", buf);
- zip_close(zfd);
- }
- return 0;
- }
- int testStat(int argc, char** argv)
- {
- struct stat buf;
- if (argc < 2) {
- LOGE("parameter is error! :%s filepath", argv[0]);
- return -1;
- }
- zip_stat(argv[1], &buf);
- return 0;
- }
- int main(int argc, char** argv)
- {
- //testReadEntry(argc, argv);
- //testIsInZip(argc, argv);
- //testRead(argc, argv);
- testStat(argc, argv);
- return 0;
- }
Android.mk
- LOCAL_PATH:= $(call my-dir)
- #################################
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:= \
- zip_wrapper.cpp
- LOCAL_CFLAGS :=
- LOCAL_SHARED_LIBRARIES := libutils
- LOCAL_C_INCLUDES := .
- LOCAL_MODULE_TAGS:= optional
- LOCAL_MODULE:= libreadzip
- include $(BUILD_STATIC_LIBRARY)
- #################################
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:= \
- zip_main.cpp
- LOCAL_CFLAGS :=
- LOCAL_STATIC_LIBRARIES := libreadzip
- LOCAL_SHARED_LIBRARIES := libutils
- LOCAL_C_INCLUDES := .
- LOCAL_MODULE_TAGS:= optional
- LOCAL_MODULE:= readzip
- include $(BUILD_EXECUTABLE)
- [zip]android下实现直接读取zip中的文件
- [zip]android下实现直接读取zip中的文件
- Android无需解压直接读取Zip文件和文件内容
- 读取ZIP中的txt文件
- Android 不解压直接读取zip包
- iOS 读取zip包中的文件
- VC 下读取ZIP文件API
- android studio 读取assets中zip文件
- 读取zip文件
- 读取ZIP文件
- zip文件解压读取
- ZIP 文件读取
- 读取zip文件
- ios读取zip文件
- 读取zip文件
- Java无需解压直接读取Zip文件和文件内容
- Java无需解压直接读取Zip文件和文件内容
- Java无需解压直接读取Zip文件和文件内容
- 算法的力量
- 关于AFNetworking框架的使用
- C# List<T>用法
- GDAL功能模块列表
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台(C#开发)-数据库设计
- [zip]android下实现直接读取zip中的文件
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台九(C#开发)-空间数据导入RDBMS上-Shape格式
- file操作
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台(C#开发)-背景介绍
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台(C#开发)-(GIS)地理信息系统简介
- windows xp系统左下角音量图标不显示的一种解决办法
- 第五堂课后作业
- 基于ArcGIS10.0和Oracle10g的空间数据管理平台(C#开发)-系统需求分析
- courage