SSZipArchive 解压后 中文文件名乱码问题

不知道什么情况,做为一个三方广泛使用的框架库,会出现这种比较低级的问题!

还有中文的文件名解压后显示乱码!

 经过深入研究排查,发现目录或文件名编码错误!但是POD库,不可能直接在里面改!只能进行封装修改!

 修复后的显示:

修复文件代码:头文件

 

//
//  ZipRar7zUnArchive.h
//  ZipRar7zUnArchive
//
//  Created by Saravanan V on 26/04/13.
//  Copyright (c) 2013 SARAVANAN. All rights reserved.
//#import <Foundation/Foundation.h>
#import <SSZipArchive/SSZipArchive.h>#define UNIQUE_KEY( x ) NSString * const x = @#xenum{SARFileTypeZIP,SARFileTypeRAR
};static UNIQUE_KEY( rar );
static UNIQUE_KEY( zip );typedef void(^completionBlock)(BOOL result);@interface ZipRar7zUnArchive : NSObject{
}+ (BOOL)isPasswordProtectedAtPath:(NSString *)path;+ (BOOL)unarchiveFrom:(NSString *)filePath toPath:(NSString *)topath password:(NSString *)password;
@end

实现逻辑:

//
//  ZipRar7zUnArchive.m
//  ZipRar7zUnArchive
//
//  Created by Saravanan V on 26/04/13.
//  Copyright (c) 2013 SARAVANAN. All rights reserved.
//#import "ZipRar7zUnArchive.h"#import <UnrarKit/UnrarKit.h>
#import "LzmaSDKObjC.h"#import "SSZipCommon.h"
#import "mz_compat.h"
#import "mz_zip.h"#include <zlib.h>
#include <sys/stat.h>@interface ZipRar7zUnArchive ()<SSZipArchiveDelegate>{
}
@property (nonatomic, strong) SSZipArchive *zipArchive;@property (nonatomic, strong) NSString *filePath;
@property (nonatomic, strong) NSString *password;
@property (nonatomic, strong) NSString *destinationPath;
@end@implementation ZipRar7zUnArchive+ (ZipRar7zUnArchive *)instance
{static dispatch_once_t onceToken;static ZipRar7zUnArchive *m = nil;dispatch_once(&onceToken, ^{m = [[ZipRar7zUnArchive alloc] init];});return m;
}#pragma mark - Init Methods
+ (BOOL)unarchiveFrom:(NSString *)filePath toPath:(NSString *)topath password:(NSString *)password
{ZipRar7zUnArchive *a = [ZipRar7zUnArchive instance];[a setFilePath:filePath];[a setDestinationPath:topath];[a setPassword:password];return [a decompress];
}+ (BOOL)isPasswordProtectedAtPath:(NSString *)path
{NSError *archiveError = nil;//URKArchive用来判断是否要输入密码,filePath是要解压的文件路径URKArchive *archive = [[URKArchive alloc] initWithPath:path error:&archiveError];if ([archive isPasswordProtected]) {return YES;}return NO;
}#pragma mark - Helper Methods
- (NSString *)fileType{NSArray *derivedPathArr = [_filePath componentsSeparatedByString:@"/"];NSString *lastObject = [derivedPathArr lastObject];NSString *fileType = [[lastObject componentsSeparatedByString:@"."] lastObject];return [fileType lowercaseString];
}#pragma mark - Decompressing Methods
- (BOOL)decompress{//    NSLog(@"_fileType : %@",_fileType);if ( [[self fileType] compare:rar options:NSCaseInsensitiveSearch] == NSOrderedSame ) {return [self rarDecompress];}else if ( [[self fileType] compare:zip options:NSCaseInsensitiveSearch] == NSOrderedSame ) {return [self zipDecompress];}else if ( [[self fileType] compare:@"7z" options:NSCaseInsensitiveSearch] == NSOrderedSame ) {return [self decompress7z];}return NO;
}- (BOOL)rarDecompress {
//    _filePath = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"rar"];NSLog(@"filePath : %@",_filePath);NSLog(@"destinationPath : %@",_destinationPath);NSError *archiveError = nil;URKArchive *archive = [[URKArchive alloc] initWithPath:_filePath error:&archiveError];if (!archive) {NSLog(@"Failed!");return NO;}NSError *error = nil;NSArray *filenames = [archive listFilenames:&error];if (archive.isPasswordProtected) {archive.password = self.password;}if (error) {NSLog(@"Error reading archive: %@", error);return NO;}//    for (NSString *filename in filenames) {
//        NSLog(@"File: %@", filename);
//    }// Extract a file into memory just to validate if it works/extracts[archive extractDataFromFile:filenames[0] progress:nil error:&error];if (error) {if (error.code == ERAR_MISSING_PASSWORD) {NSLog(@"Password protected archive! Please provide a password for the archived file.");}return NO;}else {return true;}
}- (BOOL)zipDecompress{/*BOOL unzipped = [SSZipArchive unzipFileAtPath:_filePath toDestination:_destinationPath delegate:self];*/BOOL unzipped = [SSZipArchive unzipFileAtPath:self.filePath toDestination:self.destinationPath fileName:[self.destinationPath lastPathComponent] preserveAttributes:YES overwrite:YES nestedZipLevel:0 password:nil error:nil delegate:self progressHandler:nil completionHandler:nil];;
//    NSLog(@"unzipped : %d",unzipped);NSError *error;if (self.password != nil && self.password.length > 0) {
//        unzipped = [SSZipArchive unzipFileAtPath:_filePath toDestination:_destinationPath overwrite:NO password:self.password error:&error delegate:self];
//        unzipped = [SSZipArchive unzipFileAtPath:_filePath toDestination:_destinationPath fileName:@"" preserveAttributes:YES overwrite:NO nestedZipLevel:0 password:self.password error:error delegate:self progressHandler:nil completionHandler:nil];NSLog(@"error: %@", error);}return unzipped;
}- (BOOL)decompress7z{NSLog(@"_filePath: %@", _filePath);NSLog(@"_destinationPath: %@", _destinationPath);//    LzmaSDKObjCReader *reader = [[LzmaSDKObjCReader alloc] initWithFileURL:[NSURL fileURLWithPath:_filePath]];// 1.2 Or create with predefined archive type if path doesn't containes suitable extensionLzmaSDKObjCReader *reader = [[LzmaSDKObjCReader alloc] initWithFileURL:[NSURL fileURLWithPath:_filePath] andType:LzmaSDKObjCFileType7z];//    // Optionaly: assign weak delegate for tracking extract progress.
//    reader.delegate = self;// If achive encrypted - define password getter handler.// NOTES:// - Encrypted file needs password for extract process.// - Encrypted file with encrypted header needs password for list(iterate) and extract archive items.reader.passwordGetter = ^NSString*(void){
//        return @"password to my achive";NSLog(@"self.password: %@", self.password);return self.password;};// Open archive, with or without error. Error can be nil.NSError * error = nil;if (![reader open:&error]) {NSLog(@"Open error: %@", error);}NSLog(@"Open error: %@", reader.lastError);NSMutableArray *filePathsArray = [NSMutableArray array];NSMutableArray * items = [NSMutableArray array]; // Array with selected items.// Iterate all archive items, track what items do you need & hold them in array.[reader iterateWithHandler:^BOOL(LzmaSDKObjCItem * item, NSError * error){
//        NSLog(@"\nitem:%@", item);if (item) {[items addObject:item]; // if needs this item - store to array.if (!item.isDirectory) {NSString *filePath = [_destinationPath stringByAppendingPathComponent:item.directoryPath];filePath = [filePath stringByAppendingPathComponent:item.fileName];[filePathsArray addObject:filePath];}}return YES; // YES - continue iterate, NO - stop iteration}];NSLog(@"Iteration error: %@", reader.lastError);// Extract selected items from prev. step.// YES - create subfolders structure for the items.// NO - place item file to the root of path(in this case items with the same names will be overwrited automaticaly).[reader extract:itemstoPath:_destinationPathwithFullPaths:YES];NSLog(@"Extract error: %@", reader.lastError);// Test selected items from prev. step.[reader test:items];NSLog(@"test error: %@", reader.lastError);if (reader.lastError || ![filePathsArray count]) {return NO;}else {return YES;}
}#pragma mark - Utility Methods
- (NSString *) applicationDocumentsDirectory
{NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;return basePath;
}@endBOOL _afileIsSymbolicLink(const unz_file_info *fileInfo)
{//// Determine whether this is a symbolic link:// - File is stored with 'version made by' value of UNIX (3),//   as per https://www.pkware.com/documents/casestudies/APPNOTE.TXT//   in the upper byte of the version field.// - BSD4.4 st_mode constants are stored in the high 16 bits of the//   external file attributes (defacto standard, verified against libarchive)//// The original constants can be found here://    https://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/include/sys/stat.h//const uLong ZipUNIXVersion = 3;const uLong BSD_SFMT = 0170000;const uLong BSD_IFLNK = 0120000;BOOL fileIsSymbolicLink = ((fileInfo->version >> 8) == ZipUNIXVersion) && BSD_IFLNK == (BSD_SFMT & (fileInfo->external_fa >> 16));return fileIsSymbolicLink;
}@interface SSZipArchive (extra)
+ (BOOL)unzipFileAtPath:(NSString *)pathtoDestination:(NSString *)destinationfileName:(NSString *)fileNamepreserveAttributes:(BOOL)preserveAttributesoverwrite:(BOOL)overwritenestedZipLevel:(NSInteger)nestedZipLevelpassword:(nullable NSString *)passworderror:(NSError **)errordelegate:(nullable id<SSZipArchiveDelegate>)delegateprogressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandlercompletionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;+ (NSString *)filenameStringWithCString:(const char *)filenameversion_made_by:(uint16_t)version_made_bygeneral_purpose_flag:(uint16_t)flagsize:(uint16_t)size_filename;
@end@implementation SSZipArchive (extra)+ (BOOL)unzipFileAtPath:(NSString *)pathtoDestination:(NSString *)destinationfileName:(NSString *)fileNamepreserveAttributes:(BOOL)preserveAttributesoverwrite:(BOOL)overwritenestedZipLevel:(NSInteger)nestedZipLevelpassword:(nullable NSString *)passworderror:(NSError **)errordelegate:(nullable id<SSZipArchiveDelegate>)delegateprogressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandlercompletionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler
{// Guard against empty stringsif (path.length == 0 || destination.length == 0){NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"received invalid argument(s)"};NSError *err = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeInvalidArguments userInfo:userInfo];if (error){*error = err;}if (completionHandler){completionHandler(nil, NO, err);}return NO;}// Begin openingzipFile zip = unzOpen(path.fileSystemRepresentation);if (zip == NULL){NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open zip file"};NSError *err = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFailedOpenZipFile userInfo:userInfo];if (error){*error = err;}if (completionHandler){completionHandler(nil, NO, err);}return NO;}NSDictionary * fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];unsigned long long fileSize = [[fileAttributes objectForKey:NSFileSize] unsignedLongLongValue];unsigned long long currentPosition = 0;unz_global_info globalInfo = {};unzGetGlobalInfo(zip, &globalInfo);// Begin unzippingint ret = 0;ret = unzGoToFirstFile(zip);if (ret != UNZ_OK && ret != MZ_END_OF_LIST){NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open first file in zip file"};NSError *err = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFailedOpenFileInZip userInfo:userInfo];if (error){*error = err;}if (completionHandler){completionHandler(nil, NO, err);}unzClose(zip);return NO;}BOOL success = YES;BOOL canceled = NO;int crc_ret = 0;unsigned char buffer[4096] = {0};NSFileManager *fileManager = [NSFileManager defaultManager];NSMutableArray<NSDictionary *> *directoriesModificationDates = [[NSMutableArray alloc] init];// Message delegateif ([delegate respondsToSelector:@selector(zipArchiveWillUnzipArchiveAtPath:zipInfo:)]) {[delegate zipArchiveWillUnzipArchiveAtPath:path zipInfo:globalInfo];}if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {[delegate zipArchiveProgressEvent:currentPosition total:fileSize];}NSInteger currentFileNumber = -1;NSError *unzippingError;do {currentFileNumber++;if (ret == MZ_END_OF_LIST) {break;}@autoreleasepool {if (password.length == 0) {ret = unzOpenCurrentFile(zip);} else {ret = unzOpenCurrentFilePassword(zip, [password cStringUsingEncoding:NSUTF8StringEncoding]);}if (ret != UNZ_OK) {unzippingError = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:SSZipArchiveErrorCodeFailedOpenFileInZip userInfo:@{NSLocalizedDescriptionKey: @"failed to open file in zip file"}];success = NO;break;}// Reading data and write to fileunz_file_info fileInfo;memset(&fileInfo, 0, sizeof(unz_file_info));ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);if (ret != UNZ_OK) {unzippingError = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:SSZipArchiveErrorCodeFileInfoNotLoadable userInfo:@{NSLocalizedDescriptionKey: @"failed to retrieve info for file"}];success = NO;unzCloseCurrentFile(zip);break;}currentPosition += fileInfo.compressed_size;// Message delegateif ([delegate respondsToSelector:@selector(zipArchiveShouldUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {if (![delegate zipArchiveShouldUnzipFileAtIndex:currentFileNumbertotalFiles:(NSInteger)globalInfo.number_entryarchivePath:pathfileInfo:fileInfo]) {success = NO;canceled = YES;break;}}if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {[delegate zipArchiveWillUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entryarchivePath:path fileInfo:fileInfo];}if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {[delegate zipArchiveProgressEvent:(NSInteger)currentPosition total:(NSInteger)fileSize];}char *filename = (char *)malloc(fileInfo.size_filename + 1);if (filename == NULL){success = NO;break;}unzGetCurrentFileInfo(zip, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0);filename[fileInfo.size_filename] = '\0';BOOL fileIsSymbolicLink = _afileIsSymbolicLink(&fileInfo);const char *cname = [fileName cStringUsingEncoding:NSUTF8StringEncoding];NSString * strPath = [SSZipArchive filenameStringWithCString:filenameversion_made_by:fileInfo.versiongeneral_purpose_flag:fileInfo.flagsize:fileInfo.size_filename];if ([strPath hasPrefix:@"__MACOSX/"]) {// ignoring resource forks: https://superuser.com/questions/104500/what-is-macosx-folderunzCloseCurrentFile(zip);ret = unzGoToNextFile(zip);
//                free(filename);continue;}// Check if it contains directoryBOOL isDirectory = NO;if (filename[fileInfo.size_filename-1] == '/' || filename[fileInfo.size_filename-1] == '\\') {isDirectory = YES;}free(filename);// Sanitize paths in the file name.strPath = [strPath _sanitizedPath];if (!strPath.length) {// if filename data is unsalvageable, we default to currentFileNumberstrPath = @(currentFileNumber).stringValue;}NSString *fullPath = [destination stringByAppendingPathComponent:strPath];NSError *err = nil;NSDictionary *directoryAttr;if (preserveAttributes) {NSDate *modDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.mz_dos_date];directoryAttr = @{NSFileCreationDate: modDate, NSFileModificationDate: modDate};[directoriesModificationDates addObject: @{@"path": fullPath, @"modDate": modDate}];}if (isDirectory) {[fileManager createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:directoryAttr error:&err];} else {[fileManager createDirectoryAtPath:fullPath.stringByDeletingLastPathComponent withIntermediateDirectories:YES attributes:directoryAttr error:&err];}if (err != nil) {if ([err.domain isEqualToString:NSCocoaErrorDomain] &&err.code == 640) {unzippingError = err;unzCloseCurrentFile(zip);success = NO;break;}NSLog(@"[SSZipArchive] Error: %@", err.localizedDescription);}if ([fileManager fileExistsAtPath:fullPath] && !isDirectory && !overwrite) {//FIXME: couldBe CRC Check?unzCloseCurrentFile(zip);ret = unzGoToNextFile(zip);continue;}if (isDirectory && !fileIsSymbolicLink) {// nothing to read/write for a directory} else if (!fileIsSymbolicLink) {// ensure we are not creating stale file entriesint readBytes = unzReadCurrentFile(zip, buffer, 4096);if (readBytes >= 0) {FILE *fp = fopen(fullPath.fileSystemRepresentation, "wb");while (fp) {if (readBytes > 0) {if (0 == fwrite(buffer, readBytes, 1, fp)) {if (ferror(fp)) {NSString *message = [NSString stringWithFormat:@"Failed to write file (check your free space)"];NSLog(@"[SSZipArchive] %@", message);success = NO;unzippingError = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:SSZipArchiveErrorCodeFailedToWriteFile userInfo:@{NSLocalizedDescriptionKey: message}];break;}}} else {break;}readBytes = unzReadCurrentFile(zip, buffer, 4096);if (readBytes < 0) {// Let's assume error Z_DATA_ERROR is caused by an invalid password// Let's assume other errors are caused by Content Not Readablesuccess = NO;}}if (fp) {fclose(fp);if (nestedZipLevel&& [fullPath.pathExtension.lowercaseString isEqualToString:@"zip"]&& [self unzipFileAtPath:fullPathtoDestination:fullPath.stringByDeletingLastPathComponentpreserveAttributes:preserveAttributesoverwrite:overwritenestedZipLevel:nestedZipLevel - 1password:passworderror:nildelegate:nilprogressHandler:nilcompletionHandler:nil]) {[directoriesModificationDates removeLastObject];[[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];} else if (preserveAttributes) {// Set the original datetime propertyif (fileInfo.mz_dos_date != 0) {NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.mz_dos_date];NSDictionary *attr = @{NSFileModificationDate: orgDate};if (attr) {if (![fileManager setAttributes:attr ofItemAtPath:fullPath error:nil]) {// Can't set attributesNSLog(@"[SSZipArchive] Failed to set attributes - whilst setting modification date");}}}// Set the original permissions on the file (+read/write to solve #293)uLong permissions = fileInfo.external_fa >> 16 | 0b110000000;if (permissions != 0) {// Store it into a NSNumberNSNumber *permissionsValue = @(permissions);// Retrieve any existing attributesNSMutableDictionary *attrs = [[NSMutableDictionary alloc] initWithDictionary:[fileManager attributesOfItemAtPath:fullPath error:nil]];// Set the value in the attributes dict[attrs setObject:permissionsValue forKey:NSFilePosixPermissions];// Update attributesif (![fileManager setAttributes:attrs ofItemAtPath:fullPath error:nil]) {// Unable to set the permissions attributeNSLog(@"[SSZipArchive] Failed to set attributes - whilst setting permissions");}}}}else{// if we couldn't open file descriptor we can validate global errno to see the reasonint errnoSave = errno;BOOL isSeriousError = NO;switch (errnoSave) {case EISDIR:// Is a directory// assumed casebreak;case ENOSPC:case EMFILE:// No space left on device//  or// Too many open filesisSeriousError = YES;break;default:// ignore case// Just log the error{NSError *errorObject = [NSError errorWithDomain:NSPOSIXErrorDomaincode:errnoSaveuserInfo:nil];NSLog(@"[SSZipArchive] Failed to open file on unzipping.(%@)", errorObject);}break;}if (isSeriousError) {// serious caseunzippingError = [NSError errorWithDomain:NSPOSIXErrorDomaincode:errnoSaveuserInfo:nil];unzCloseCurrentFile(zip);// Log the errorNSLog(@"[SSZipArchive] Failed to open file on unzipping.(%@)", unzippingError);// Break unzippingsuccess = NO;break;}}} else {// Let's assume error Z_DATA_ERROR is caused by an invalid password// Let's assume other errors are caused by Content Not Readablesuccess = NO;break;}}else{// Assemble the path for the symbolic linkNSMutableString *destinationPath = [NSMutableString string];int bytesRead = 0;while ((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0){buffer[bytesRead] = 0;[destinationPath appendString:@((const char *)buffer)];}if (bytesRead < 0) {// Let's assume error Z_DATA_ERROR is caused by an invalid password// Let's assume other errors are caused by Content Not Readablesuccess = NO;break;}// Check if the symlink exists and delete it if we're overwritingif (overwrite){if ([fileManager fileExistsAtPath:fullPath]){NSError *localError = nil;BOOL removeSuccess = [fileManager removeItemAtPath:fullPath error:&localError];if (!removeSuccess){NSString *message = [NSString stringWithFormat:@"Failed to delete existing symbolic link at \"%@\"", localError.localizedDescription];NSLog(@"[SSZipArchive] %@", message);success = NO;unzippingError = [NSError errorWithDomain:SSZipArchiveErrorDomain code:localError.code userInfo:@{NSLocalizedDescriptionKey: message}];}}}// Create the symbolic link (making sure it stays relative if it was relative before)int symlinkError = symlink([destinationPath cStringUsingEncoding:NSUTF8StringEncoding],[fullPath cStringUsingEncoding:NSUTF8StringEncoding]);if (symlinkError != 0){// Bubble the error up to the completion handlerNSString *message = [NSString stringWithFormat:@"Failed to create symbolic link at \"%@\" to \"%@\" - symlink() error code: %d", fullPath, destinationPath, errno];NSLog(@"[SSZipArchive] %@", message);success = NO;unzippingError = [NSError errorWithDomain:NSPOSIXErrorDomain code:symlinkError userInfo:@{NSLocalizedDescriptionKey: message}];}}crc_ret = unzCloseCurrentFile(zip);if (crc_ret == MZ_CRC_ERROR) {// CRC ERRORsuccess = NO;break;}ret = unzGoToNextFile(zip);// Message delegateif ([delegate respondsToSelector:@selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {[delegate zipArchiveDidUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entryarchivePath:path fileInfo:fileInfo];} else if ([delegate respondsToSelector: @selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:unzippedFilePath:)]) {[delegate zipArchiveDidUnzipFileAtIndex: currentFileNumber totalFiles: (NSInteger)globalInfo.number_entryarchivePath:path unzippedFilePath: fullPath];}if (progressHandler){progressHandler(strPath, fileInfo, currentFileNumber, globalInfo.number_entry);}}} while (ret == UNZ_OK && success);// CloseunzClose(zip);// The process of decompressing the .zip archive causes the modification times on the folders// to be set to the present time. So, when we are done, they need to be explicitly set.// set the modification date on all of the directories.if (success && preserveAttributes) {NSError * err = nil;for (NSDictionary * d in directoriesModificationDates) {if (![[NSFileManager defaultManager] setAttributes:@{NSFileModificationDate: [d objectForKey:@"modDate"]} ofItemAtPath:[d objectForKey:@"path"] error:&err]) {NSLog(@"[SSZipArchive] Set attributes failed for directory: %@.", [d objectForKey:@"path"]);}if (err) {NSLog(@"[SSZipArchive] Error setting directory file modification date attribute: %@", err.localizedDescription);}}}// Message delegateif (success && [delegate respondsToSelector:@selector(zipArchiveDidUnzipArchiveAtPath:zipInfo:unzippedPath:)]) {[delegate zipArchiveDidUnzipArchiveAtPath:path zipInfo:globalInfo unzippedPath:destination];}// final progress event = 100%if (!canceled && [delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {[delegate zipArchiveProgressEvent:fileSize total:fileSize];}NSError *retErr = nil;if (crc_ret == MZ_CRC_ERROR){NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"crc check failed for file"};retErr = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFileInfoNotLoadable userInfo:userInfo];}if (error) {if (unzippingError) {*error = unzippingError;}else {*error = retErr;}}if (completionHandler){if (unzippingError) {completionHandler(path, success, unzippingError);}else{completionHandler(path, success, retErr);}}return success;
}+ (NSString *)filenameStringWithCString:(const char *)filenameversion_made_by:(uint16_t)version_made_bygeneral_purpose_flag:(uint16_t)flagsize:(uint16_t)size_filename
{// Respect Language encoding flag only reading filename as UTF-8 when this is set// when file entry created on dos system.//// https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT//   Bit 11: Language encoding flag (EFS).  If this bit is set,//           the filename and comment fields for this file//           MUST be encoded using UTF-8. (see APPENDIX D)uint16_t made_by = version_made_by >> 8;BOOL made_on_dos = made_by == 0;BOOL languageEncoding = (flag & (1 << 11)) != 0;if (!languageEncoding && made_on_dos) {// APPNOTE.TXT D.1://   D.2 If general purpose bit 11 is unset, the file name and comment should conform//   to the original ZIP character encoding.  If general purpose bit 11 is set, the//   filename and comment must support The Unicode Standard, Version 4.1.0 or//   greater using the character encoding form defined by the UTF-8 storage//   specification.  The Unicode Standard is published by the The Unicode//   Consortium (www.unicode.org).  UTF-8 encoded data stored within ZIP files//   is expected to not include a byte order mark (BOM).//  Code Page 437 corresponds to kCFStringEncodingDOSLatinUSNSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingDOSChineseSimplif);NSString* strPath = [NSString stringWithCString:filename encoding:encoding];if (strPath) {return strPath;}}// attempting unicode encodingNSString * strPath = @(filename);if (strPath) {return strPath;}// if filename is non-unicode, detect and transform EncodingNSData *data = [NSData dataWithBytes:(const void *)filename length:sizeof(unsigned char) * size_filename];
// Testing availability of @available (https://stackoverflow.com/a/46927445/1033581)
#if __clang_major__ < 9// Xcode 8-if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_9_2) {
#else// Xcode 9+if (@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)) {
#endif// supported encodings are in [NSString availableStringEncodings][NSString stringEncodingForData:data encodingOptions:nil convertedString:&strPath usedLossyConversion:nil];} else {// fallback to a simple manual detect for macOS 10.9 or olderNSArray<NSNumber *> *encodings = @[@(kCFStringEncodingGB_18030_2000), @(kCFStringEncodingShiftJIS)];for (NSNumber *encoding in encodings) {strPath = [NSString stringWithCString:filename encoding:(NSStringEncoding)CFStringConvertEncodingToNSStringEncoding(encoding.unsignedIntValue)];if (strPath) {break;}}}if (strPath) {return strPath;}// if filename encoding is non-detected, we default to something based on data// _hexString is more readable than _base64RFC4648 for debugging unknown encodingsstrPath = [data _hexString];return strPath;
}
@end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/40727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Objective-C语法基础

注&#xff1a;编译器版本 XCode 15.4 新建一个XCode项目 新建一个类 1、成员变量、属性 1.1、类内使用成员变量&#xff0c;类外使用属性 Role.h #import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGINinterface Role : NSObject {//成员变量&#xff1a;只能…

Ubuntu18.04安装AutoWare.ai(完整版)

目录 目录 一、安装Opencv 1.1 下载安装包Opencv官网 1.2 安装opencv_contrib 二、安装Eigen库 1. 解压文件 2. 安装Eigen 3. 配置路径&#xff1a; 三、安装Ros和rosdepc 四、安装Autoware.ai-1.14.0 4.1 安装依赖 4.2 下载Autoware.ai 1.在home路径下打开终端输…

RUP开发模型-系统架构师(二十三)

1、RUP是一个二维软件开发模型&#xff0c;其核心特点之一是&#xff08;&#xff09;。RUP将软件开发周期划分多个循环&#xff0c;每个循环由4个连续阶段组成&#xff0c;每个阶段完成确定的任务。设计及确定系统的体系结构&#xff0c;制定工作计划及资源要求在&#xff08;…

【AI学习】无线AI的问题和挑战

无线AI&#xff0c;即无线人工智能&#xff0c;是指内生于未来&#xff08;6G&#xff09;无线通信系统并通过无线架构、无线数据、无线算法和无线应用所呈现出来的新的人工智能技术体系。 最近一直在进行无线AI的调研&#xff0c;感觉真的是路漫漫其修远兮。业界有一些探索&a…

CVPR 2024最佳论文:“神兵”的组合器 Generative Image Dynamics

CVPR 2024的最佳论文来自谷歌、美国加州大学圣迭戈分校。两篇都来至于视频生成领域&#xff0c;可见今年外界对视频生成领域关注度很高。今天的这篇是“Generative Image Dynamics”&#xff0c;Google Research发布的。它的研究成果令人震惊&#xff0c;从单张RGB图像生成连续…

远程监控在工业机械安全操作中的应用——以汽车起重机为例

远程监控技术&#xff0c;作为现代信息技术的重要分支&#xff0c;正逐渐在各个领域展现其独特的价值。从字面上理解&#xff0c;远程监控可以分为“监”和“控”两部分&#xff1a;其中&#xff0c;“监”指的是通过网络进行信息的获取与传递&#xff0c;实现远程状态的实时感…

stm32——定时器级联

在STM32当中扩展定时范围&#xff1a;单个定时器的定时长度可能无法满足某些应用的需求。通过级联&#xff0c;可以实现更长时间的定时&#xff1b;提高定时精度&#xff1a;能够在长定时的基础上&#xff0c;通过合理配置&#xff0c;实现更精细的定时控制&#xff1b;处理复杂…

【后端面试题】【中间件】【NoSQL】MongoDB查询过程、ESR规则、覆盖索引的优化

任何中间件的面试说到底都是以高可用、高性能和高并发为主&#xff0c;而高性能和高并发基本是同时存在的。 性能优化一直被看作一个高级面试点&#xff0c;因为只有对原理了解得很透彻的人&#xff0c;在实践中才能找准性能优化的关键点&#xff0c;从而通过各种优化手段解决性…

【营销策划模型大全】私域运营必备

营销策划模型大全&#xff1a;战略屋品牌屋、电商运营模型、营销战略、新媒体运营模型、品牌模型、私域运营模型…… 该文档是一份策划总监工作模型的汇总&#xff0c;包括战略屋/品牌屋模型、营销战略模型、品牌相关模型、电商运营模型、新媒体运营模型和私域运营模型等&…

【你真的了解double和float吗】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a;基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 …

Buuctf之不一样的flag(迷宫题)

首先&#xff0c;进行查壳无壳&#xff0c;32bit&#xff0c;丢进ida32中进行反编译进入main函数&#xff0c;对其进行分析&#xff0c;可以在一旁打上注释&#xff0c;这边最关键的一个点就是&#xff0c;需要联想到这是一个迷宫题&#xff0c;很小的迷宫题&#xff0c;迷宫就…

(十三)MipMap

MipMap概念 滤波 采样 mipmap级别判定 问题&#xff1a;opengl如何判定应该使用下一级的mipmap呢&#xff1f; 通过glsl中的求偏导函数计算变化量决定 手动实现mipmap原理 1、生成mipmap的各个级别 2、修改vertexShader使得三角形随着时间变小 **** 需要更改Filter才能…

事务底层与高可用原理

1.事务底层与高可用原理 事务的基础知识 mysql的事务分为显式事务和隐式事务 默认的事务是隐式事务 显式事务由我们自己控制事务的开启&#xff0c;提交&#xff0c;回滚等操作 show variables like autocommit; 事务基本语法 事务开始 1、begin 2、START TRANSACTION&…

透过 Go 语言探索 Linux 网络通信的本质

大家好&#xff0c;我是码农先森。 前言 各种编程语言百花齐放、百家争鸣&#xff0c;但是 “万变不离其中”。对于网络通信而言&#xff0c;每一种编程语言的实现方式都不一样&#xff1b;但其实&#xff0c;调用的底层逻辑都是一样的。linux 系统底层向上提供了统一的 Sock…

三菱PLC标签使用(I/O的映射)与内容

今天&#xff0c;小编继续开始三菱PLC的学习&#xff0c;今天的内容是标签及其标签的内容说明&#xff0c;如果对你有帮助&#xff0c;欢迎评论收藏。 标签的种类&#xff0c;等级&#xff0c;定义 种类 三菱3U的PLC的种类分别为二种&#xff1a;全局标签与局部标签 全局标签…

操作审计(一)

操作审计&#xff08;一&#xff09; 前言一、快速查询事件二、高级查询事件总结 前言 这里主要记录操作审计的过程&#xff0c;操作审计其实就是监控并记录阿里云账号的活动&#xff0c;可以使用阿里云的操作审计服务来审计最近90天阿里云账号下的操作&#xff0c;从而确保云…

RKNN3588——YOLOv8的PT模型转RKNN模型

一&#xff1a;PT转ONNX 1. 首先克隆rknn修改后的ultralytics版本项目到本地 https://github.com/airockchip/ultralytics_yolov8 cd ultralytics-main pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple pip install -e . 主要是修改了源码的ul…

PhpStorm 2024 for Mac PHP集成开发工具

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff08;适合自己的M芯片版或Intel芯片版&#xff09;&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功3、打开访达&#xff0c;点击【文…

如何在TikTok上获得更多观看量:12个流量秘诀

TikTok作为热门海外社媒&#xff0c;在跨境出海行业中成为新兴的推广渠道&#xff0c;但你知道如何让你的TikTok赢得更多关注次数吗&#xff1f;如果您正在寻找增加 TikTok 观看次数的方法&#xff0c;接下来这12种策略&#xff0c;你需要一一做好&#xff01; 1. 在内容中添加…

HQ-SAM

不建议复现