iOS文件解压缩、带密码解压缩、压缩文件情况处理

2017年上半年,忙碌的半年,直到现在才有时间总结总结之前几个月用到的相关技术,记录下来,跟大家分享。
之前在做一个与H5混合开发的应用时,我负责处理大文件(也就是H5应用包)的下载、解压、MD5校验等工作。下载文件,大家肯定并不陌生,有很多种方法可以完成,大家可以选择自己熟悉或者适合自己项目的下载框架去完成,我使用的是NSURLSession。关于下载的具体细节在这里不再阐述,稍后我会继续写一篇博文主要介绍大文件下载和异步下载并存储问题,今天主要介绍iOS文件的代码解压和压缩问题。
关于解压和压缩,我找到了一个好用的框架ZipArchive。当然,大家有什么好的资源也可以互相交流,在这里我主要讲解关于ZipArchive的使用。
首先,导入ZipArchive文件,其次,将ZipArchive.mm改为使用MRC,在Buid Setting里的Build Phases的Compile Sources找到ZipArchive.mm文件,在它后面添加-fno-obje-arc.最后就是关于ZipArchive的方法的调用了。
导入#import “ZipArchive.h”
1.解压有密码的文件

ZipArchive *za = [[ZipArchive alloc] init];
    // 1打开文件,并在内存中解压
    if ([za UnzipOpenFile:zipPath Password:@"123"]) {
        // 2把解压出的内存写入caches目录
        BOOL ret = [za UnzipFileTo:dirPath overWrite:YES];
        if (NO == ret){
            NSLog(@"%@解压失败",FileName);


        }else{
            NSLog(@"%@解压成功",FileName);


        }

        [[NSFileManager defaultManager] removeItemAtPath:zipPath error:nil];


        [za UnzipCloseFile];
2.解压无密码的文件
ZipArchive *za = [[ZipArchive alloc] init];
            //无密码解压压缩包
            if ([za UnzipOpenFile:md5path]) {
                BOOL ret = [za UnzipFileTo:dirpath overWrite:YES];
                if (NO == ret){
                    NSLog(@"无密码解压失败");
                }else{
                    NSLog(@"无密码解压成功");
                    [[NSFileManager defaultManager] removeItemAtPath:md5path error:nil];
                }
                [za UnzipCloseFile];
            }
以上是关于带密码解压和无密码解压的两个方法的调用,其中的zipPath和md5Path是你要解压的zip包的文件路径,dirPath是你解压后的文件保存的路径。
ZipAchive还有两个关于压缩文件的方法,即:
-(BOOL) CreateZipFile2:(NSString*) zipFile;
-(BOOL) CreateZipFile2:(NSString*) zipFile Password:(NSString*) password;
大家可以自己去调用一下试试。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哈夫曼编码是一种基于字符频率的压缩算法,可以在不丢失数据的情况下有效地减小文件大小。哈夫曼编码的压缩过程需要先建立哈夫曼树,再根据哈夫曼树生成每个字符的编码表,最后将原文件中的字符替换为对应的编码即可。解压过程则是将编码转换为原字符,最终还原原始文件。 以下是一个简单的哈夫曼树编码文件压缩解压缩的实现示例,使用 C++ 语言编写。 ### 哈夫曼树的构建 ```cpp #include <iostream> #include <queue> #include <vector> #include <unordered_map> using namespace std; // 哈夫曼树节点 struct Node { char ch; int freq; Node *left, *right; Node(char c, int f) : ch(c), freq(f), left(nullptr), right(nullptr) {} }; // 比较器,用于优先队列中的排序 struct cmp { bool operator()(Node* a, Node* b) { return a->freq > b->freq; } }; // 构建哈夫曼树 Node* buildHuffmanTree(string str) { // 统计字符频率 unordered_map<char, int> freqMap; for (char c : str) { freqMap[c]++; } // 将所有字符及其频率转化为哈夫曼树节点并加入优先队列 priority_queue<Node*, vector<Node*>, cmp> pq; for (auto it = freqMap.begin(); it != freqMap.end(); it++) { pq.push(new Node(it->first, it->second)); } // 构建哈夫曼树 while (pq.size() > 1) { Node* left = pq.top(); pq.pop(); Node* right = pq.top(); pq.pop(); Node* parent = new Node('$', left->freq + right->freq); parent->left = left; parent->right = right; pq.push(parent); } // 返回根节点 return pq.top(); } ``` ### 哈夫曼编码的生成 ```cpp // 生成哈夫曼编码表 void generateEncodingTable(Node* root, unordered_map<char, string>& encodingTable, string code) { if (!root) return; if (!root->left && !root->right) { encodingTable[root->ch] = code; return; } generateEncodingTable(root->left, encodingTable, code + "0"); generateEncodingTable(root->right, encodingTable, code + "1"); } ``` ### 文件压缩 ```cpp #include <fstream> #include <bitset> // 压缩文件 void compressFile(string inputFile, string outputFile) { // 读取原文件 ifstream ifs(inputFile, ios::binary); string str((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>())); ifs.close(); // 构建哈夫曼树并生成编码表 Node* root = buildHuffmanTree(str); unordered_map<char, string> encodingTable; generateEncodingTable(root, encodingTable, ""); // 将编码表写入压缩文件头部 ofstream ofs(outputFile, ios::binary); for (auto it = encodingTable.begin(); it != encodingTable.end(); it++) { ofs << it->first << it->second << endl; } // 将压缩后的内容写入压缩文件 string compressedStr; for (char c : str) { compressedStr += encodingTable[c]; } while (compressedStr.length() % 8 != 0) compressedStr += "0"; // 补齐到8的倍数 for (int i = 0; i < compressedStr.length(); i += 8) { bitset<8> bits(compressedStr.substr(i, 8)); ofs << char(bits.to_ulong()); } ofs.close(); } ``` ### 文件解压 ```cpp #include <sstream> // 解压文件 void decompressFile(string inputFile, string outputFile) { // 读取压缩文件 ifstream ifs(inputFile, ios::binary); stringstream ss; ss << ifs.rdbuf(); string compressedStr = ss.str(); ifs.close(); // 从压缩文件头部读取编码表 unordered_map<string, char> decodingTable; int i = 0; while (i < compressedStr.length() && compressedStr[i] != '\n') { char c = compressedStr[i++]; string code; while (i < compressedStr.length() && compressedStr[i] != '\n') { code += compressedStr[i++]; } decodingTable[code] = c; i++; // 跳过换行符 } // 解压缩内容 string decompressedStr; string code; for (; i < compressedStr.length(); i++) { bitset<8> bits(compressedStr[i]); code += bits.to_string(); if (decodingTable.find(code) != decodingTable.end()) { decompressedStr += decodingTable[code]; code.clear(); } } // 写入解压后的内容 ofstream ofs(outputFile, ios::binary); ofs << decompressedStr; ofs.close(); } ``` 以上就是一个简单的哈夫曼树编码文件压缩解压缩的实现方法。需要注意的是,在实际应用中,还需要考虑一些细节问题,例如文件读写、编码表的存储方式和压缩文件头部的格式等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值