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.rhkb.cn/news/368185.html

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

相关文章

【大数据】—美国交通事故分析(2016 年 2 月至 2020 年 12 月)

引言 在当今快速发展的数字时代&#xff0c;大数据已成为我们理解世界、做出决策的重要工具。特别是在交通安全领域&#xff0c;大数据分析能够揭示事故模式、识别风险因素&#xff0c;并帮助制定预防措施&#xff0c;从而挽救生命。本文将深入探讨2016年2月至2020年12月期间&…

数据结构——树的基础概念

目录 1.树的概念 2.树的相关概念 3.树的表示 &#xff08;1&#xff09;直接表示法 &#xff08;2&#xff09;双亲表示法 (3)左孩子右兄弟表示法 4.树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 1.树的概念 树是一种非线性的数据结构&#xff0…

9.计算机视觉—目标检测

目录 1.物体检测边缘框目标检测数据集总结边缘框代码实现2.锚框:目标检测的一种方法IoU—交并比赋予锚框标号使用非极大值抑制(NMS)输出总结代码实现1.物体检测 边缘框 一个边缘框可以通过四个数字定义 (左上x,左上y),(右下x,右下y)(左上x,左上y,宽,高)(中间x,中间y…

数字人直播源码开发全攻略揭秘:如何搭建自己的数字人直播平台?

当前&#xff0c;数字人直播逐渐成为众多中小型企业线上带货和品牌宣传的不二之选&#xff0c;而艾媒研究数据也显示&#xff0c;超五成以上的被调查群体的企业使用过虚拟人技术&#xff0c;超三成被调查群体的企业计划使用虚拟人技术。在此背景下&#xff0c;越来越多的创业者…

CSS-实例-div 水平居中 垂直靠上

1 需求 2 语法 3 示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>表格水平居中、垂直靠上示例…

如何加密U盘?U盘加密软件推荐

U盘是我们最常用的移动存储设备&#xff0c;可以帮助我们随身携带大量数据。为了避免U盘数据泄露&#xff0c;我们需要加密保护U盘。那么&#xff0c;U盘该如何加密呢&#xff1f;下面小编就为大家推荐两款专业的U盘加密软件。 U盘超级加密3000 U盘超级加密3000是一款优秀的U盘…

Linux高并发服务器开发(十一)UDP通信和本地socket通信

文章目录 1 TCP和UDP的区别2 UDPAPI流程服务端流程客户端流程 代码服务端客户端 3 本地socket通信服务端客户端客户端代码 1 TCP和UDP的区别 2 UDP API 流程 服务端流程 客户端流程 代码 服务端 #include<sys/socket.h> #include<stdio.h> #include<arpa/in…

14-23 深度神经网络的主要架构(RNN/LSTM/CNN)

神经网络架构 神经网络的架构决定了这些网络如何运行&#xff0c;这是执行各种任务和扩展神经网络应用的关键因素&#xff0c;主要有两种方法&#xff1a;前馈神经网络和反馈神经网络。在本文中&#xff0c;在彻底分析每种方法之后&#xff0c;我们将对这两种架构进行深入比较…

工商业光伏项目如何快速开发?

一、前期调研与规划 1、屋顶资源评估&#xff1a;详细测量屋顶面积、承重能力及朝向&#xff0c;利用光伏业务管理软件进行日照分析和发电量预测&#xff0c;确保项目可行性。 2、政策与补贴研究&#xff1a;深入了解当地政府对工商业光伏项目的政策支持和补贴情况&#xff0…

亚马逊云服务器的价格真的那么贵吗?一年要花多少钱?

亚马逊Web服务&#xff08;AWS&#xff09;作为全球领先的云计算平台&#xff0c;其定价策略常常引起用户的关注。很多人可能会问&#xff1a;"AWS真的那么贵吗&#xff1f;"实际上&#xff0c;这个问题的答案并不是简单的"是"或"否"&#xff0c…

vue table表格 ( parseTime-格式化时间)

<el-table-column label"发布时间" width"420px" prop"bidPublishDatetime"><template slot-scope"scope"><span>{{ parseTime(scope.row.bidPublishDatetime, {y}-{m}-{d}) }}</span></template></…

宝塔Linux面板配置环境 + 创建站点

一、安装 &#xff08;1&#xff09;进入宝塔官网 https://www.bt.cn/new/index.html &#xff08;2&#xff09;点击“ 立即免费安装 ”&#xff0c;选择 Centos安装脚本 &#xff08;3&#xff09;进入 ssh 输入以下命令安装宝塔 yum install -y wget && wget -O …

Go语言工程管理

本文内容为Go工程创建和配置开发及简单程序示例。 目录 工程管理 GOPATH 配置GOPATH GOROOT 新建系统变量 配置go工程 添加go path 简单的程序实现 程序代码 开始运行 运行结果 内容解析 总结 工程管理 GOPATH go语言的项目&#xff0c;需要有特定的目录结构进行…

FMEA在大型光伏电站安全生产管理中的应用

一、FMEA概述 FMEA&#xff08;Failure Modes and Effects Analysis&#xff09;即失效模式和影响分析&#xff0c;是一种用于识别和分析产品或过程中潜在故障模式及其影响的方法。它通过对产品或过程中可能出现的故障模式进行系统性地梳理和分析&#xff0c;评估其可能的影响…

ORA-12170: TNS:连接超时

今天在oracle数据库搭建连接远程数据库的dbink时&#xff0c;发现搭建失败报错&#xff1a;ORA-12170: TNS:连接超时 但是是能够ping的通远程数据库地址的。 telnet 172.18.6.104 1522要求查看下创建dblink语句&#xff0c;也确认创建语句无误。 (DESCRIPTION (ADDRESS_LIST…

用Python轻松转换Markdown文件为PDF文档

Markdown&#xff0c;以其简洁的语法和易于阅读的特性&#xff0c;成为了许多作家、开发者和学生记录思想、编写教程或撰写报告的首选格式。然而&#xff0c;在分享或打印这些文档时&#xff0c;Markdown的纯文本形式可能无法满足对版式和布局的专业需求。而将Markdown转换为PD…

基于C++实现的EventLoop与事件驱动编程

一&#xff0c;概念介绍 事件驱动编程&#xff08;Event-Driven&#xff09;是一种编码范式&#xff0c;常被应用在图形用户界面&#xff0c;应用程序&#xff0c;服务器开发等场景。 采用事件驱动编程的代码中&#xff0c;通常要有事件循环&#xff0c;侦听事件&#xff0c;…

无线物联网题集

测试一 未来信息产业的发展在由信息网络向 全面感知和 智能应用两个方向拓展、延伸和突破。 各国均把 物联网作为未来信息化战略的重要内容,融合各种信息技术,突破互联网的限制,将物体接入信息网络。 计算机的出现,开始了第四次工业革命,开始了人机物的高度融合&#xff08;&…

数据库安全审计系统:满足数据安全治理合规要求

伴随着数据库信息价值以及可访问性提升&#xff0c;使得数据库面对来自内部和外部的安全风险大大增加&#xff0c;如违规越权操作、恶意入侵导致机密信息窃取泄漏&#xff0c;但事后却无法有效追溯和审计。 国内专注于保密与非密领域的分级保护、等级保护、业务连续性安全和大数…