Objective-C-ZIP 라이브러리를 사용하여 폴더 구조를 유지하면서 zip화

15320 단어 MacOSXObjective-Czip

Objective-C-ZIP 라이브러리를 사용하여 폴더 구조를 유지하면서 zip화



배경


  • POSIX 함수의 zip -rj ... 로 하려고 했지만, 폴더가 포함되지 않기 때문에 불가. (모든 파일이 루트 폴더에 설치됩니다.)
  • 터미널처럼 cd 를 하고…

  • zip 에서는 한계가 있다 (폴더 구조가 유지되지 않는 등) 때문에, Objective-Zipライブラリ 를 사용할 필요에 달려 있었다.

  • Objective-Zip 이라는 외부 라이브러리를 사용한다.

  • 예상 출력 결과


  • 하기 파일 구조를 유지한 채로 zip화를 실시한다.
  • 아래 폴더를 다운로드 폴더 바로 아래에 배치


  • 만든 zip 파일과 압축 해제 결과



  • CocoaPods에서 라이브러리 추가



    아래를 참고로 도입.

    htps : // m / pekoka lyp / ms / b80f6c343355 872 6
    htps : // m / 사토 켄 0417 / ms / 479bcdf91cf2634fb1
    Podfile 는 아래와 같다.platform :osx, '10.13.0' 의 지정으로 좋은가는 자신이 없다.
    # Uncomment the next line to define a global platform for your project
    # platform :ios, '9.0'
    platform :osx, '10.13.0'
    pod 'objective-zip', '~> 1.0'
    
    target 'ObjectiveC_ZIP_LIB_TEST' do
      # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
      # use_frameworks!
    
      # Pods for ObjectiveC_ZIP_LIB_TEST
    
    end
    

    Github의 README 보충



    Objective-Zip의 사용법에 대해서는 기본 README를 참조한다.
    다만 GitHub의 설명대로 zip 파일을 작성하면 압축해제로 에러가 발생한다. (아래 코드로 하면 오류가 발생한다)
        OZZipFile* zip = [[OZZipFile alloc] initWithFileName:@"test.zip" mode:OZZipFileModeCreate];
        OZZipWriteStream* write = [zip writeFileInZipWithName:@"hello.txt"
                                           compressionLevel:OZZipCompressionLevelBest];
        NSData* data = [@"hello" dataUsingEncoding:NSUTF8StringEncoding];
        [write writeData:data];
        [write finishedWriting];
        [zip close];
    



    64bit 모드에 문제가 있다고 합니다.


    You are having trouble with the 64 bit mode that objective-zip can use.

    If you just add legacy32BitMode:YES when creating the archive, everything will be fine.

    32bit 모드를 사용하면 좋다고 합니다.
    OZZipFile *zipFile= [[OZZipFile alloc] initWithFileName:zipPath 
                                                       mode:OZZipFileModeCreate 
                                            legacy32BitMode:YES];
    

    zip에서 폴더 구조를 유지하려면



    폴더 구조는 각 파일을 zip화할 때 경로 지정으로 하는 것으로 작성한다.

    File/folder hierarchy inide the zip
    Please note that inside the zip files there is no representation of a file-folder hierarchy: it is simply embedded in file names (i.e.: a file with a name like "x/y/z/file.txt"). It is up to the program that extracts files to consider these file names as expressing a structure and rebuild it on the file system (and viceversa during creation). Common zippers/unzippers simply follow this rule.

    예: relativeFilePath@"x/y/z/file.txt" 를 지정합니다.
    OZZipWriteStream *zipWriteStream = [zip writeFileInZipWithName:relativeFilePath
                                                          compressionLevel:OZZipCompressionLevelBest];
    

    작성한 프로그램



    서두


    #import "AppDelegate.h"
    #import "Objective-Zip.h"
    static NSString *const kTargetFolderPath = @"~/Downloads/SampleFolder"; // zip化対象フォルダ
    static NSString *const kZipName          = @"result.zip";               // zip化する際のファイル名
    

    호출부


    NSString *targetFolderPath = [kTargetFolderPath stringByExpandingTildeInPath];
    [self zipFilesWithFolderURL:[NSURL fileURLWithPath:targetFolderPath] zipName:kZipName];
    

    기능부


    /**
     @brief フォルダ構造を保ったままフォルダ内のファイルのzip化を行う
     @param dirURL zip化対象フォルダ
     @param aZipName 作成するzip名
     */
    - (void)zipFilesWithFolderURL:(NSURL *)dirURL zipName:(NSString *)aZipName {
        NSArray   *fileURLList = [self getFileURLListWithFolderURL:dirURL];
        NSString  *zipPath     = [NSBundle.mainBundle.bundlePath.stringByDeletingLastPathComponent stringByAppendingPathComponent:aZipName];
        OZZipFile *zip         = [[OZZipFile alloc] initWithFileName:zipPath
                                                                mode:OZZipFileModeCreate
                                                     legacy32BitMode:YES];
        for (NSURL *fileURL in fileURLList) {
            // zip内の構造を示すための、相対パスを作成する
            NSMutableString *relativeFilePath = [[NSMutableString alloc] initWithString:fileURL.path];
            NSRange range = [relativeFilePath rangeOfString:dirURL.path];
            [relativeFilePath deleteCharactersInRange:range]; // 相対パス部分のみ残す
    
            OZZipWriteStream *zipWriteStream = [zip writeFileInZipWithName:relativeFilePath
                                                          compressionLevel:OZZipCompressionLevelBest];
            NSData* fileData = [NSData dataWithContentsOfURL:fileURL];
            [zipWriteStream writeData:fileData];
            [zipWriteStream finishedWriting];
        }
        [zip close];
        return;
    }
    
    /**
     @brief 対象フォルダ内の全ファイルのURL配列を取得する
     @param aDirectory 検索対象フォルダ
     @return ファイルのURL配列
     @warning pkg及び隠しファイル及びサブフォルダ自体を無視
     */
    - (NSArray *)getFileURLListWithFolderURL:(NSURL *)aDirectory {
        NSMutableArray *fileURLList = [NSMutableArray array];
        // フォルダ内のファイルのパスを順番に取得する
        NSFileManager *fileManager = NSFileManager.defaultManager;
        // ディレクトリ用の列挙子を取得する(pkg及び隠しファイルは除外する)
        NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:aDirectory
                                              includingPropertiesForKeys:nil
                                                                 options:NSDirectoryEnumerationSkipsPackageDescendants | NSDirectoryEnumerationSkipsHiddenFiles
                                                            errorHandler:nil];
        for (NSURL *subURL in enumerator) {
            BOOL isDir = NO;
            [fileManager fileExistsAtPath:subURL.path isDirectory:&isDir];
            if (isDir) {
                continue;   // フォルダは対象外
            }
            [fileURLList addObject:subURL];
        }
        return fileURLList.copy;
    }
    

    좋은 웹페이지 즐겨찾기