2009-07-30 24 views
9

有誰知道任何庫/代碼,使我的編碼和解碼的.tar格式化數據 - 我可以在我的iPhone項目中使用(最好是可可)TAR編碼/解碼庫的iPhone(理想情況下可可)

在此先感謝

克雷格

更新:我已經看到了在建議庫和前來,他們正在waaaay得多了問題的結論 - 所以我開發了自己的編解碼器 - 它畢竟只是一個512字節的ASCII標頭 - 它有多難:-)

+0

在谷歌「焦油庫C」 http://www.feep.net/libtar/ – KevinDTimm 2009-07-30 07:20:02

+0

克雷格發現的第一個項目,你有沒有在這裏找到一個很好的答案......或者你自己的執行進展情況?就我所知,這是API空間中的一個大漏洞。另外:我設法將libtar編譯到iPhone友好的靜態庫中,但這是一個痛苦的過程,我在測試用例中遇到了一些崩潰,這讓我基本上認爲我不得不放棄整個方向。 – 2010-04-17 00:02:43

回答

2

實際上,libarchive.dylib包含在iPhone SDK中。你只需要添加它。問題是蘋果公司沒有包含頭文件archive.h。但是,首先,如果確實知道要調用的函數存在(即使編譯器會發牢騷),則不需要頭文件;其次,如果您不希望編譯器發出抱怨,則可以下載頭文件爲libarchive 2.6並將其包含在您的程序中...

如果您想知道使用libarchive,請從網上下載它的源代碼並研究給出的示例(特別是minitar)。這真的很直接。

+0

我相信這使得無證,這意味着你不能使用它。但我可能是錯的。 – 2010-11-16 22:35:20

+1

請在下面看到我的回覆。 `libarchive`是所有版本iOS上的私有API。要成爲公共API,(1)庫二進制文件必須位於SDK中,(2)頭文件必須位於SDK中。 – 2010-11-18 01:03:58

+0

在Mac OS上是libarchive公開的嗎? – Enchilada 2011-06-15 17:34:07

5

我發現最好的圖書館是libarchive。它設計精良,文件齊全,速度快。

我剛剛在GitHub上創建了一個存儲庫,該存儲庫具有將libarchivelibbz2作爲iOS 4.2+的靜態庫的工具。 (應該可以用它來針對3.X,太。)

http://github.com/davepeck/iOS-libarchive/

其他人則指出,libarchive包含在SDK中。這不完全正確。包含二進制libarchive.2.dylib,但標題不包含。這同樣適用於libbz2(但奇怪的是,不是libz。)這意味着libarchive被視爲私有API--換句話說,如果您打算在App Store上發佈,則無法使用它。因此我的存儲庫。

1

對於libarchive,只需將「libarchive」添加到框架列表中即可使用,但缺少頭文件。您可以從libarchive源複製標題。或者,如果你想保持它的簡單,試試這個:

//////////////////////////////////////////////////////////////////////////////////////////////////// 
// LibArchive "Header" - ios is missing this header. go figure. 
//////////////////////////////////////////////////////////////////////////////////////////////////// 

// from ftp://ftp8.freebsd.org/pub/FreeBSD/FreeBSD-current/src/lib/libarchive/archive.h.in 

#define  ARCHIVE_EOF    1   /* Found end of archive. */ 
#define  ARCHIVE_OK     0   /* Operation was successful. */ 
#define  ARCHIVE_RETRY   (-10)  /* Retry might succeed. */ 
#define  ARCHIVE_WARN    (-20)  /* Partial success. */ 
#define  ARCHIVE_FAILED   (-25)  /* Current operation cannot complete. */ 
#define  ARCHIVE_FATAL   (-30)  /* No more operations are possible. */ 

struct archive; 
struct archive_entry; 

int    archive_version_number(void); 
const char *  archive_version_string(void); 
int    archive_version_stamp(void); 
const char *  archive_version(void); 
int    archive_api_version(void); 
int    archive_api_feature(void); 
typedef ssize_t archive_read_callback(struct archive *, void *_client_data, const void **_buffer); 
//typedef ssize_t archive_skip_callback(struct archive *, void *_client_data, size_t request); 
typedef off_t  archive_skip_callback(struct archive *, void *_client_data, off_t request); 
typedef ssize_t archive_write_callback(struct archive *, void *_client_data, const void *_buffer, size_t _length); 
typedef int  archive_open_callback(struct archive *, void *_client_data); 
typedef int  archive_close_callback(struct archive *, void *_client_data); 
struct   archive *archive_read_new(void); 
int    archive_read_support_compression_all(struct archive *); 
int    archive_read_support_compression_bzip2(struct archive *); 
int    archive_read_support_compression_compress(struct archive *); 
int    archive_read_support_compression_gzip(struct archive *); 
int    archive_read_support_compression_none(struct archive *); 
int    archive_read_support_compression_program(struct archive *, const char *command); 
int    archive_read_support_format_all(struct archive *); 
int    archive_read_support_format_ar(struct archive *); 
int    archive_read_support_format_cpio(struct archive *); 
int    archive_read_support_format_empty(struct archive *); 
int    archive_read_support_format_gnutar(struct archive *); 
int    archive_read_support_format_iso9660(struct archive *); 
int    archive_read_support_format_mtree(struct archive *); 
int    archive_read_support_format_tar(struct archive *); 
int    archive_read_support_format_zip(struct archive *); 
int    archive_read_open(struct archive *, void *_client_data, archive_open_callback *, archive_read_callback *, archive_close_callback *); 
int    archive_read_open2(struct archive *, void *_client_data, archive_open_callback *, archive_read_callback *, archive_skip_callback *, archive_close_callback *); 
int    archive_read_open_filename(struct archive *, const char *_filename, size_t _block_size); 
int    archive_read_open_file(struct archive *, const char *_filename, size_t _block_size); 
int    archive_read_open_memory(struct archive *, void * buff, size_t size); 
int    archive_read_open_memory2(struct archive *a, void *buff, size_t size, size_t read_size); 
int    archive_read_open_fd(struct archive *, int _fd, size_t _block_size); 
int    archive_read_open_FILE(struct archive *, FILE *_file); 
int    archive_read_next_header(struct archive *, struct archive_entry **); 
int64_t   archive_read_header_position(struct archive *); 
ssize_t   archive_read_data(struct archive *, void *, size_t); 
int    archive_read_data_block(struct archive *a, const void **buff, size_t *size, off_t *offset); 
int    archive_read_data_skip(struct archive *); 
int    archive_read_data_into_buffer(struct archive *, void *buffer, ssize_t len); 
int    archive_read_data_into_fd(struct archive *, int fd); 
int    archive_read_extract(struct archive *, struct archive_entry *, int flags); 
void    archive_read_extract_set_progress_callback(struct archive *, void (*_progress_func)(void *), void *_user_data); 
void    archive_read_extract_set_skip_file(struct archive *, dev_t, ino_t); 
int    archive_read_close(struct archive *); 
int    archive_read_finish(struct archive *); 
//void    archive_read_finish(struct archive *); 
struct   archive *archive_write_new(void); 
int    archive_write_set_bytes_per_block(struct archive *, int bytes_per_block); 
int    archive_write_get_bytes_per_block(struct archive *); 
int    archive_write_set_bytes_in_last_block(struct archive *, int bytes_in_last_block); 
int    archive_write_get_bytes_in_last_block(struct archive *); 
int    archive_write_set_skip_file(struct archive *, dev_t, ino_t); 
int    archive_write_set_compression_bzip2(struct archive *); 
int    archive_write_set_compression_compress(struct archive *); 
int    archive_write_set_compression_gzip(struct archive *); 
int    archive_write_set_compression_none(struct archive *); 
int    archive_write_set_compression_program(struct archive *, const char *cmd); 
int    archive_write_set_format(struct archive *, int format_code); 
int    archive_write_set_format_by_name(struct archive *, const char *name); 
int    archive_write_set_format_ar_bsd(struct archive *); 
int    archive_write_set_format_ar_svr4(struct archive *); 
int    archive_write_set_format_cpio(struct archive *); 
int    archive_write_set_format_cpio_newc(struct archive *); 
int    archive_write_set_format_pax(struct archive *); 
int    archive_write_set_format_pax_restricted(struct archive *); 
int    archive_write_set_format_shar(struct archive *); 
int    archive_write_set_format_shar_dump(struct archive *); 
int    archive_write_set_format_ustar(struct archive *); 
int    archive_write_open(struct archive *, void *, archive_open_callback *, archive_write_callback *, archive_close_callback *); 
int    archive_write_open_fd(struct archive *, int _fd); 
int    archive_write_open_filename(struct archive *, const char *_file); 
int    archive_write_open_file(struct archive *, const char *_file); 
int    archive_write_open_FILE(struct archive *, FILE *); 
int    archive_write_open_memory(struct archive *, void *_buffer, size_t _buffSize, size_t *_used); 
int    archive_write_header(struct archive *, struct archive_entry *); 
ssize_t   archive_write_data(struct archive *, const void *, size_t); 
//int    archive_write_data(struct archive *, const void *, size_t); 
ssize_t   archive_write_data_block(struct archive *, const void *, size_t, off_t); 
int    archive_write_finish_entry(struct archive *); 
int    archive_write_close(struct archive *); 
int    archive_write_finish(struct archive *); 
//void    archive_write_finish(struct archive *); 
struct   archive *archive_write_disk_new(void); 
int    archive_write_disk_set_skip_file(struct archive *, dev_t, ino_t); 
int    archive_write_disk_set_options(struct archive *, int flags); 
int    archive_write_disk_set_standard_lookup(struct archive *); 
int    archive_write_disk_set_group_lookup(struct archive *, void *private_data, gid_t (*loookup)(void *, const char *gname, gid_t gid), void (*cleanup)(void *)); 
int    archive_write_disk_set_user_lookup(struct archive *, void *private_data, uid_t (*)(void *, const char *uname, uid_t uid), void (*cleanup)(void *)); 
int64_t   archive_position_compressed(struct archive *); 
int64_t   archive_position_uncompressed(struct archive *); 
const char *  archive_compression_name(struct archive *); 
int    archive_compression(struct archive *); 
int    archive_errno(struct archive *); 
const char *  archive_error_string(struct archive *); 
const char *  archive_format_name(struct archive *); 
int    archive_format(struct archive *); 
void    archive_clear_error(struct archive *); 
void    archive_set_error(struct archive *, int _err, const char *fmt, ...); 
void    archive_copy_error(struct archive *dest, struct archive *src); 

// From ftp://ftp8.freebsd.org/pub/FreeBSD/FreeBSD-current/src/lib/libarchive/archive_entry.h 

time_t   archive_entry_atime(struct archive_entry *); 
long    archive_entry_atime_nsec(struct archive_entry *); 
time_t   archive_entry_ctime(struct archive_entry *); 
long    archive_entry_ctime_nsec(struct archive_entry *); 
dev_t    archive_entry_dev(struct archive_entry *); 
dev_t    archive_entry_devmajor(struct archive_entry *); 
dev_t    archive_entry_devminor(struct archive_entry *); 
mode_t   archive_entry_filetype(struct archive_entry *); 
void    archive_entry_fflags(struct archive_entry *, unsigned long *set, unsigned long *clear); 
const char*  archive_entry_fflags_text(struct archive_entry *); 
gid_t    archive_entry_gid(struct archive_entry *); 
const char*  archive_entry_gname(struct archive_entry *); 
const wchar_t* archive_entry_gname_w(struct archive_entry *); 
const char*  archive_entry_hardlink(struct archive_entry *); 
const wchar_t* archive_entry_hardlink_w(struct archive_entry *); 
ino_t    archive_entry_ino(struct archive_entry *); 
mode_t   archive_entry_mode(struct archive_entry *); 
time_t   archive_entry_mtime(struct archive_entry *); 
long    archive_entry_mtime_nsec(struct archive_entry *); 
unsigned int  archive_entry_nlink(struct archive_entry *); 
const char*  archive_entry_pathname(struct archive_entry *); 
const wchar_t* archive_entry_pathname_w(struct archive_entry *); 
dev_t    archive_entry_rdev(struct archive_entry *); 
dev_t    archive_entry_rdevmajor(struct archive_entry *); 
dev_t    archive_entry_rdevminor(struct archive_entry *); 
int64_t   archive_entry_size(struct archive_entry *); 
const char*  archive_entry_strmode(struct archive_entry *); 
const char*  archive_entry_symlink(struct archive_entry *); 
const wchar_t* archive_entry_symlink_w(struct archive_entry *); 
uid_t    archive_entry_uid(struct archive_entry *); 
const char*  archive_entry_uname(struct archive_entry *); 
const wchar_t* archive_entry_uname_w(struct archive_entry *); 

我只關心讀書,所以我沒有與一些archive_entry.h突變功能打擾。此外,一些方法已被註釋掉。這些是獲得#ifdef'd的不同版本的替代品。祝你好運和良好的錯誤狩獵!

下面是用它來解壓在iOS歸檔到一個目錄下的一個樣本:他們都可以作爲的CocoaPods

+ (void)unpackArchive: (NSData*) archiveData 
{ 
    int r; 
    struct archive* a; 
    struct archive_entry *entry; 
    const char *entry_path; 
    NSString *baseDir = [self baseDir]; 
    NSFileHandle* file; 
    NSError* error; 
    NSDictionary* result = @{}; 

    NSLog(@"Unpacking %d byte static assets tarball into %@", [archiveData length], baseDir); 

    if (![[NSFileManager defaultManager] createDirectoryAtPath:baseDir 
            withIntermediateDirectories:YES 
                attributes:nil 
                 error:&error]) 
    { 
     NSLog(@"Create directory error: %@", error); 
    } 

    a = archive_read_new(); 
    archive_read_support_format_gnutar(a); 
    archive_read_support_format_tar(a); 
    archive_read_support_compression_gzip(a); 

    r = archive_read_open_memory(a, (void*)[archiveData bytes], [archiveData length]); 
    if (r != ARCHIVE_OK) { 
     NSLog(@"ERROR[%d] in archive_read_open_file(): %s", r, archive_error_string(a)); 
     return; 
    } 
    for (;;) { 
     r = archive_read_next_header(a, &entry); 
     if (r == ARCHIVE_EOF) { 
      break; 
     } 
     if (r != ARCHIVE_OK) { 
      NSLog(@"ERROR[%d] in archive_read_next_header(): %s", r, archive_error_string(a)); 
      return; 
     } 
     entry_path = archive_entry_pathname(entry); 

     NSString* path = [baseDir stringByAppendingPathComponent: [NSString stringWithUTF8String: entry_path]]; 
     NSLog(@"Tarball Entry: %s", entry_path); 

     // Create the file and blank it out 
     [[NSFileManager defaultManager] createFileAtPath: path contents:[[NSMutableData alloc] init] attributes:nil]; 
     // Actually write the file 
     file = [NSFileHandle fileHandleForWritingAtPath:path]; 
     r = archive_read_data_into_fd(a, [file fileDescriptor]); 
     if (r != ARCHIVE_OK) { 
      NSLog(@"ERROR[%d] in archive_read_data_into_fd(): %s", r, archive_error_string(a)); 
      return; 
     } 
     [file closeFile]; 
    } 
    r = archive_read_close(a); 
    if (r != ARCHIVE_OK) { 
     NSLog(@"ERROR[%d] in archive_read_close(): %s", r, archive_error_string(a)); 
     return; 
    } 
} 

---戴夫

0

似乎有是兩個更現代化的圖書館, :

  • NVHTarGzip:支持進度報告,同時具有同步和異步方法。不支持tar寫入。
  • tarkit:支持tar寫入,但沒有其他好的功能。

兩者都非常相似,因爲它們都基於Light-Untar-for-iOS

相關問題