Tôi chưa thấy bất kỳ tài liệu nào về chủ đề này, nhưng điều đó không có nghĩa là nó không tồn tại.Có cách nào thực tế để nén NSData không?
Trả lời
Có, nén dữ liệu bằng zlib.
@ Brad Larson đăng trên: see here và thêm mã này.
Có một số CocoaPod sử dụng Objective-Zip bởi flyingdolphinstudio.
Theo dõi @Zaph & Bài đăng của @Brad Larson, bên dưới là 2 phương pháp gzipInflate
và gzipDeflate
hoạt động tốt để nén/giải nén NSData
. (Mã định dạng lại từ 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];
}
Từ nhật ký:
[data length] (orig):989631
[data length] (gz): 102757
[data length] (ungz):989631
Wow, điều này thật tuyệt! Cảm ơn –
@Rayay nếu muốn sử dụng bzip2 thay vì gzip, hãy xem [bài đăng này] (http://stackoverflow.com/questions/9577735/how-compress-data-in-memory-buffer-by-using-libbz2-library -in-c-program/11390277 # 11390277). –
Trông rất đẹp, nhưng khi biên dịch, Xcode nói _BZ2_bzCompressEnd và bạn bè là các ký hiệu không xác định cho armv7. –
Tôi đã thực hiện một giao diện nén Objective-C BZip2 đẹp sẵn như là một CocoaPod: https://github.com/blakewatters/BZipCompression
Hãy thử điều này: https://github.com/mattt/Godzippa Đó là hữu ích cho tôi
Bắt đầu với iOS 9.0, có hỗ trợ tích hợp cho một vài thuật toán nén hơn. thư viện được gọi là libcompression và hỗ trợ LZ4, LZMA, ZLIB và LZFSE.
Dưới đây là ví dụ Swift về cách sử dụng tính năng nén để giải nén LZMA. Đó là tiết, nhưng tránh phụ thuộc bên ngoài và có thể bị ẩn trong phần mở rộng trên 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
}
Trình bao bọc Swift 3 sẵn sàng xung quanh quá trình nén. https://github.com/mw99/SwiftDataCompression
libcompression wrapper Swift như một phần mở rộng cho các loại dữ liệu (ZLIB, LZFSE, LZMA, LZ4, deflate, RFC-1950, RFC-1951)
Thú vị để chơi với ở sân chơi : playground compression rates
- 1. rel = "tooltip", có thực tế không?
- 2. Dự án Darkstar có thực tế không?
- 3. Có cách nào để in truy vấn thực tế mà mysqli-> execute() tạo ra không?
- 4. Có cách nào để tạo đầu ra jQuery * đánh dấu thực tế * không?
- 5. Có cách nào để lấy trạng thái thực tế của System.Random không?
- 6. có cách nào để xem nội dung thực tế của liên kết tượng trưng không?
- 7. Có cách nào để xác định đường dẫn lưu phiên * thực tế * không?
- 8. Làm cách nào để xác thực rằng NSData là một tệp PDF?
- 9. Sử dụng FileStream mà không cần tệp thực tế
- 10. Có cách nào thực tế để sử dụng kiểu dữ liệu phân cấp trong khung thực thể 4 không?
- 11. Việc sử dụng các trường ẩn có thực tế không?
- 12. Làm cách nào để có được tên thư mục thực tế (được bản địa hóa)?
- 13. Làm cách nào để có được lỗi thực tế đằng sau HttpResponseException?
- 14. Có cách nào để sử dụng JCrop để cắt một diện tích lớn hơn hình ảnh thực tế không?
- 15. Làm thế nào để đóng gói struct trong NSData?
- 16. Làm cách nào để giải nén/giải nén trong Emacs
- 17. Phát triển Flex không có FlexBuilder thực tế?
- 18. Làm cách nào để chuyển đổi NSString thành NSData?
- 19. Java - thực tế là không có một hàm tạo lớp?
- 20. cách xác thực tên miền quốc tế
- 21. Có thể nén javascript không nén
- 22. Làm cách nào để Dữ liệu cốt lõi có thể lưu trữ NSData?
- 23. PC thực tế trên máy phát triển cá nhân thực tế như thế nào?
- 24. Làm cách nào để nén văn bản?
- 25. NSData để mã hóa NSString
- 26. Chia đối tượng NSData thành các đối tượng NSData khác có kích thước nhất định
- 27. Có sử dụng thực tế nào của Garbage Collection của C++ 11 không?
- 28. Có cách nào hợp lý để giải nén đơn nguyên trạng thái không?
- 29. NSData writeToFile không hoạt động
- 30. Chuyển đổi NSData để int
loại nén nào? zip thẳng? Bạn có thể lấy các byte từ nó và sử dụng thư viện zip – DanZimm
Câu hỏi này hoàn toàn tương đương với "có thể nén dữ liệu không?" và câu trả lời rõ ràng là "có". –
bản sao có thể có của [API nén trên iPhone] (http://stackoverflow.com/questions/230984/compression-api-on-the-iphone) –