有没有一种实用的方法来压缩NSData?

我还没有看到关于这个主题的任何文档,但是这并不意味着它不存在。

是的,用zlib压缩数据。

@Brad Larson发布在这里: 看到这里,并添加了代码。

有一个CocoaPod使用了flyingdolphinstudio的 Objective-Zip 。

在@Zaph&@Brad Larson的post之后,下面是gzipInflategzipDeflate两个方法, gzipDeflate可以很好地压缩/解压缩NSData 。 (代码从cocoadev.com/wiki/NSDataCategory重新格式化

 #import "zlib.h" // don't forget to add libz.1.2.x.dylib into your project - (NSData *)gzipInflate:(NSData*)data { if ([data length] == 0) return data; unsigned full_length = [data length]; unsigned half_length = [data length] / 2; NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length]; BOOL done = NO; int status; z_stream strm; strm.next_in = (Bytef *)[data bytes]; strm.avail_in = [data length]; strm.total_out = 0; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; if (inflateInit2(&strm, (15+32)) != Z_OK) return nil; while (!done) { // Make sure we have enough room and reset the lengths. if (strm.total_out >= [decompressed length]) [decompressed increaseLengthBy: half_length]; strm.next_out = [decompressed mutableBytes] + strm.total_out; strm.avail_out = [decompressed length] - strm.total_out; // Inflate another chunk. status = inflate (&strm, Z_SYNC_FLUSH); if (status == Z_STREAM_END) done = YES; else if (status != Z_OK) break; } if (inflateEnd (&strm) != Z_OK) return nil; // Set real length. if (done) { [decompressed setLength: strm.total_out]; return [NSData dataWithData: decompressed]; } else return nil; } - (NSData *)gzipDeflate:(NSData*)data { if ([data length] == 0) return data; z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.total_out = 0; strm.next_in=(Bytef *)[data bytes]; strm.avail_in = [data length]; // Compresssion Levels: // Z_NO_COMPRESSION // Z_BEST_SPEED // Z_BEST_COMPRESSION // Z_DEFAULT_COMPRESSION if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil; NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chunks for expansion do { if (strm.total_out >= [compressed length]) [compressed increaseLengthBy: 16384]; strm.next_out = [compressed mutableBytes] + strm.total_out; strm.avail_out = [compressed length] - strm.total_out; deflate(&strm, Z_FINISH); } while (strm.avail_out == 0); deflateEnd(&strm); [compressed setLength: strm.total_out]; return [NSData dataWithData:compressed]; } 

从日志:

 [data length] (orig):989631 [data length] (gz): 102757 [data length] (ungz):989631 

从iOS 9.0开始,内置了对更多压缩algorithm的支持。 该库称为libcompression,支持LZ4,LZMA,ZLIB和LZFSE。

这是一个使用libcompression来解压缩LZMA的Swift示例。 它是冗长的,但是避免了外部的依赖,并且可以隐藏在NSData的扩展中。

 import Compression let streamPtr = UnsafeMutablePointer<compression_stream>.alloc(1) var stream = streamPtr.memory var status: compression_status status = compression_stream_init(&stream, COMPRESSION_STREAM_DECODE, COMPRESSION_LZMA) stream.src_ptr = UnsafePointer<UInt8>(compressedData.bytes) stream.src_size = compressedData.length let dstBufferSize: size_t = 4096 let dstBufferPtr = UnsafeMutablePointer<UInt8>.alloc(dstBufferSize) stream.dst_ptr = dstBufferPtr stream.dst_size = dstBufferSize let decompressedData = NSMutableData() repeat { status = compression_stream_process(&stream, 0) switch status { case COMPRESSION_STATUS_OK: if stream.dst_size == 0 { decompressedData.appendBytes(dstBufferPtr, length: dstBufferSize) stream.dst_ptr = dstBufferPtr stream.dst_size = dstBufferSize } case COMPRESSION_STATUS_END: if stream.dst_ptr > dstBufferPtr { decompressedData.appendBytes(dstBufferPtr, length: stream.dst_ptr - dstBufferPtr) } default: break } } while status == COMPRESSION_STATUS_OK compression_stream_destroy(&stream) if status == COMPRESSION_STATUS_END { // Decompression succeeded, do something with decompressedData } else { // Decompression failed } 

我已经做了一个很好的Objective-C BZip2压缩接口可用作CocoaPod: https : //github.com/blakewatters/BZipCompression

试试这个: https : //github.com/mattt/Godzippa这对我很有帮助。

Swift 3准备包装libcompression。 https://github.com/mw99/SwiftDataCompression

Swift的libcompression包装器作为数据types(ZLIB,LZFSE,LZMA,LZ4,deflate,RFC-1950,RFC-1951)

有趣的是在操场上玩: 操场压缩率

Interesting Posts