【问题标题】:TAR encode/decode library for iPhone (ideally cocoa) [closed]iPhone的TAR编码/解码库(最好是可可)[关闭]
【发布时间】:2010-11-15 08:24:19
【问题描述】:

有没有人知道任何库/代码可以让我编码和解码 .tar 格式的数据 - 我可以在我的 iPhone 项目中使用(最好是可可)

提前致谢

克雷格

更新:我查看了建议的库并得出结论,他们正在解决很多问题 - 所以我自己开发编解码器 - 毕竟它只是一个 512 字节的 ASCII 标头 - 如何很难:-)

【问题讨论】:

  • 在 google 'tar library c' feep.net/libtar987654321@中找到的第一个项目
  • 克雷格,你有没有在这里找到一个好的答案......或者在你自己的实施上取得了进展?据我所知,这是 API 领域的一个大漏洞。另外:我设法将 libtar 编译成 iPhone 友好的静态库,但这是一个痛苦的过程,而且我在测试用例中遇到了一些崩溃,这让我基本上认为我必须放弃整个方向。

标签: iphone cocoa-touch archive tar


【解决方案1】:

似乎还有两个更现代的库,它们都可以作为 Cocoapods 使用:

  • NVHTarGzip:支持进度报告,有同步和异步两种方式。不支持 tar 写入。
  • tarkit: 支持 tar 写入,但没有其他好的功能。

两者非常相似,因为它们都基于Light-Untar-for-iOS

【讨论】:

  • tarkit 正在生成存档实用程序未扩展的文件,优胜美地,我 tar'ed 的文件是字体文件。
  • 更正:[DCTar tarFileAtPath:filePath toPath:tarFilePath error:nil] 假设 filePath 是一个文件夹,因此如果它只是一个要 tar 的文件,它会失败...
  • contributing .tar and .tar.gz packing 之后,我最终使用了 NVHTarGzip。
【解决方案2】:

对于 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 的不同版本的替代品。祝你好运,寻找错误!

这是一个使用它来解压归档到 ios 目录的示例:

+ (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;
    }
}

--- 戴夫

【讨论】:

    【解决方案3】:

    libarchive 预装在 iOS 上。

    【讨论】:

      【解决方案4】:

      我找到的最好的库是libarchive。它设计精良、文档齐全且速度快。

      我刚刚在 GitHub 上创建了一个存储库,其中包含将 libarchivelibbz2 构建为 iOS 4.2+ 的静态库的工具。 (应该也可以使用它来定位 3.x。)

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

      其他人指出,libarchive 包含在 SDK 中。这并不完全正确。包含二进制文件libarchive.2.dylib,但不包含标头。这同样适用于libbz2(但奇怪的是,不适用于libz。)这意味着libarchive 被视为私有API——换句话说,如果您打算在应用程序上发布,则不能使用它店铺。因此我的存储库。

      【讨论】:

      • 嗨,戴夫,感谢您分享您的工作。我想知道您是否真的使用此代码向商店提交了应用程序。这个问题表明你可能仍然有问题:stackoverflow.com/questions/3507684/…
      • 链接到的项目已从存在中删除
      • libarchive 是免费软件,苹果怎么能“私有化”它?
      【解决方案5】:

      更好的链接:http://code.google.com/p/libarchive/downloads/detail?name=libarchive-2.6.2.tar.gz&can=2&q=

      版本 2.6.2 包含在 iOS 4.0 和 4.1 SDK 中。它不存在于 3.2(或我认为更早的版本)中。

      如果你下载它,运行./configure --prefix=$HOME && make && make install,你会发现两个头文件放在$HOME/include 中

      【讨论】:

      • 请看我下面的回复。 libarchive 是所有 iOS 版本上的私有 API。要成为公共 API,(1) 库二进制文件必须在 SDK 中,(2) 头文件必须在 SDK 中。
      【解决方案6】:

      事实上,libarchive.dylib 包含在 iPhone SDK 中。你只需要添加它。问题是不知何故苹果没有包含头文件archive.h。但是,首先,如果您确定要调用的函数存在,则不需要头文件(尽管编译器会抱怨),其次,如果您不希望编译器抱怨,则可以下载头文件对于 libarchive 2.6 并将其包含在您的程序中...

      如果您想知道如何使用 libarchive,请从网上下载其源代码并研究给出的示例(尤其是 minitar)。这真的很简单。

      【讨论】:

      • 我相信它是无证的,这意味着你不能使用它。但我可能是错的。
      • 请看我下面的回复。 libarchive 是所有 iOS 版本上的私有 API。要成为公共 API,(1) 库二进制文件必须在 SDK 中,(2) 头文件必须在 SDK 中。
      • libarchive 在 Mac OS 上是否公开?
      【解决方案7】:

      你可以试试libxad。这是The Unarchiver(一个 Mac 应用程序)使用的库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多