2009-07-30 9 views
9

Czy ktoś wie o wszelkich biblioteki/kod, który umożliwi mnie do kodowania i dekodowania danych w formacie tar - że mogę użyć w moim projekcie iPhone (najlepiej kakao)TAR kodowania/dekodowania biblioteki dla iPhone (idealnie kakaowego)

Dzięki z góry

Craig

UPDATE: Wziąłem spojrzeć na sugerowanych bibliotek i doszli do wniosku, że są one podejmowania waaaay za dużo problemu - tak Zajmuję kodek myself - to przecież tylko 512-bitowy nagłówek ASCII - jak ciężko to może być :-)

+0

Pierwsza pozycja znaleziona w google 'tar library c' http://www.feep.net/libtar/ – KevinDTimm

+0

Craig, czy kiedykolwiek znalazłeś tutaj dobrą odpowiedź ... lub zrobiłeś postępy we własnej implementacji? To duża dziura w przestrzeni API, o ile wiem. Również: Udało mi się skompilować libtar do przyjaznych dla iPhone'ów bibliotek statycznych, ale był to bolesny proces, w którym miałem kilka wypadków testowych, które sprawiają, że muszę porzucić cały kierunek. –

Odpowiedz

1

Możesz spróbować libxad. Jest to biblioteka używana przez aplikację Macintosh.

2

W rzeczywistości libarchive.dylib jest zawarty w pakiecie iPhone SDK. Musisz tylko to dodać. Problem w tym, że Apple w jakiś sposób nie uwzględnił pliku nagłówkowego archive.h. Najpierw jednak nie potrzebujesz plików nagłówkowych, jeśli wiesz, że istnieją funkcje, które zamierzasz wywoływać (chociaż kompilator będzie jęczeć), po drugie, jeśli nie chcesz, aby kompilator narzekał, możesz pobrać plik nagłówkowy dla libarchive 2.6 i włącz go do twojego programu ...

Jeśli chcesz wiedzieć, jak korzystać z libarchive, pobierz jego źródło z internetu i zapoznaj się z podanym przykładem (szczególnie minitar). To naprawdę bardzo proste.

+0

Wierzę, że produkuje w nieudokumentowanym, co oznacza, że ​​nie można z niego korzystać. Ale mogę się mylić. –

+1

Proszę zobaczyć moją odpowiedź poniżej. 'libarchive' to prywatny interfejs API dla WSZYSTKICH wersji systemu iOS. Aby być publicznym interfejsem API, (1) biblioteka binarna musi znajdować się w zestawie SDK, a (2) plik nagłówkowy musi znajdować się w zestawie SDK. –

+0

Czy libarchive jest publiczne w systemie Mac OS? – Enchilada

1

Nawet lepiej Link: http://code.google.com/p/libarchive/downloads/detail?name=libarchive-2.6.2.tar.gz&can=2&q=

Wersja 2.6.2 jest zawarty w iOS 4.0 i 4.1 SDK. Nie ma go w wersji 3.2 (lub wcześniej zakładam).

Jeśli pobierzesz że prowadzony ./configure --prefix=$HOME && make && make install a znajdziesz dwa pliki nagłówków umieszczonych w $ HOME/include

+0

Proszę zobaczyć moją odpowiedź poniżej. 'libarchive' to prywatny interfejs API dla WSZYSTKICH wersji systemu iOS. Aby być publicznym interfejsem API, (1) biblioteka binarna musi znajdować się w zestawie SDK, a (2) plik nagłówkowy musi znajdować się w zestawie SDK. –

5

Najlepszym biblioteka Znalazłem to libarchive. Jest dobrze zaprojektowany, dobrze udokumentowany i szybki.

Właśnie utworzyłem repozytorium na GitHub, które ma narzędzia do budowania libarchive i libbz2 jako bibliotek statycznych dla iOS 4.2+. (Powinno być możliwe użycie go do kierowania 3.x, too.)

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

Inni wskazywali, że libarchive jest zawarte w SDK. To nie jest do końca prawdą. Dołączony jest kod binarny libarchive.2.dylib, ale nagłówki nie. To samo odnosi się do libbz2 (ale, co dziwne, nie do libz.) Oznacza to, że libarchive jest uznawany za prywatny interfejs API - innymi słowy, nie można go używać, jeśli zamierzasz wysyłać w sklepie App Store. Stąd moje repozytorium.

+0

Hej Dave, dzięki za podzielenie się swoją pracą. Zastanawiam się, czy faktycznie przesłałeś aplikację do sklepu, używając tego kodu. To pytanie sugeruje, że możesz nadal mieć problemy: http://stackoverflow.com/questions/3507684/apple-private-api-rejection-with-libarchive – n8gray

+0

Projekt powiązany z został usunięty z istniejącego – jjxtra

0

Program libarchive jest fabrycznie zainstalowany na iOS.

1

Dla libarchive działa to po prostu przez dodanie "libarchive" do listy frameworków, ale brakuje nagłówka. Możesz skopiować nagłówki ze źródła zarchiwizowanego. Lub jeśli chcesz zachować proste, spróbuj tego:

//////////////////////////////////////////////////////////////////////////////////////////////////// 
// 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 *); 

ja tylko dbał o czytaniu, więc nie przejmuj się z niektórych funkcji archive_entry.h mutacji. Ponadto kilka metod zostało skomentowanych. To są alternatywy dla różnych wersji, które pobierają # ifdef. Powodzenia i polowanie na błędy!

Oto przykład wykorzystania go rozpakować archiwum do katalogu 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; 
    } 
} 

--- Dave

0

nie wydają się być dwa bardziej nowoczesne biblioteki, oba dostępne jako Cocoapods :

  • NVHTarGzip: Obsługuje raportowanie postępu i ma zarówno metody synchronizacji, jak i asynchroniczne. Nie obsługuje pisania napisów.
  • tarkit: Obsługuje pisanie smsem, ale nie ma innych fajnych funkcji.

Obaj są bardzo podobne, ponieważ są one zarówno na podstawie Light-Untar-for-iOS.

+0

tarkit tworzy pliki, które nie są rozszerzone by Archive Utility.app, Yosemite, plik i tar'ed to plik czcionki. –

+0

korekta: [DCTar tarFileAtPath: filePath toPath: tarFilePath error: nil] jest assumming, że filePath jest folderem, a więc jeśli jest to tylko jeden plik do tar, to się nie uda ... –

+0

Skończyło się na użyciu NVHTarGzip, po [przyczynieniu się '. tar' i '.tar.gz' pakowanie] (https://github.com/nvh/NVHTarGzip/pull/6) do niego. –