How To Extract Zip File In C# Windows Application
A portable (OSX/Linux/Windows/Android/iOS), unproblematic zip library written in C
This is washed by hacking awesome miniz library and layering functions on top of the miniz v2.2.0 API.
The Idea
... Some 24-hour interval, I was looking for naught library written in C for my project, only I could not find anything simple enough and lightweight. Everything what I tried required 'crazy mental gymnastics' to integrate or had some limitations or was too heavy. I hate frameworks, factories and adding new dependencies. If I must to install all those dependencies and link new library, I'yard getting almost sick. I wanted something powerfull and small enough, so I could add just a few files and compile them into my project. And finally I found miniz. Miniz is a lossless, loftier operation data compression library in a single source file. I only needed simple interface to append buffers or files to the current zip-entry. Thank you to this feature I'yard able to merge many files/buffers and shrink them on-the-fly.
Information technology was the reason, why I decided to write zippo module on top of the miniz. It required a picayune fleck hacking and wrapping some functions, but I kept simplicity. So, you can grab these three files and compile them into your project. I promise that interface is also extremely simple, and so you will non have any problems to sympathize it.
Examples
- Create a new nil annal with default compression level.
struct zip_t *zip = zip_open( "foo.zip" , ZIP_DEFAULT_COMPRESSION_LEVEL, 'w' ); { zip_entry_open(zilch, "foo-ane.txt" ); { const char *buf = "Some information hither...\0 " ; zip_entry_write(null, buf, strlen(buf)); } zip_entry_close(zip); zip_entry_open(nix, "foo-2.txt" ); { // merge iii files into i entry and compress them on-the-wing. zip_entry_fwrite(zip, "foo-2.1.txt" ); zip_entry_fwrite(zip, "foo-two.2.txt" ); zip_entry_fwrite(zilch, "foo-2.3.txt" ); } zip_entry_close(zip); } zip_close(zip);
- Append to the existing cipher archive.
struct zip_t *zip = zip_open( "foo.nada" , ZIP_DEFAULT_COMPRESSION_LEVEL, 'a' ); { zip_entry_open(zip, "foo-3.txt" ); { const char *buf = "Suspend some data here...\0 " ; zip_entry_write(zip, buf, strlen(buf)); } zip_entry_close(cipher); } zip_close(nada);
- Extract a zip archive into a folder.
int on_extract_entry(const char *filename, void *arg) { static int i = 0; int northward = *(int *)arg; printf( "Extracted: %s (%d of %d)\north " , filename, ++i, n); render 0; } int arg = ii; zip_extract( "foo.zip" , "/tmp" , on_extract_entry, &arg);
- Excerpt a zip entry into memory.
void *buf = NULL; size_t bufsize; struct zip_t *cypher = zip_open( "foo.nada" , 0, 'r' ); { zip_entry_open(nada, "foo-one.txt" ); { zip_entry_read(null, &buf, &bufsize); } zip_entry_close(null); } zip_close(naught); free(buf);
- Extract a zip entry into memory (no internal resource allotment).
unsigned char *buf; size_t bufsize; struct zip_t *goose egg = zip_open( "foo.cypher" , 0, 'r' ); { zip_entry_open(zip, "foo-1.txt" ); { bufsize = zip_entry_size(zip); buf = calloc(sizeof(unsigned char), bufsize); zip_entry_noallocread(zip, (void *)buf, bufsize); } zip_entry_close(nothing); } zip_close(zip); free(buf);
- Extract a nix entry into retentivity using callback.
struct buffer_t { char *information; size_t size; }; static size_t on_extract(void *arg, unsigned long long kickoff, const void *data, size_t size) { struct buffer_t *buf = (struct buffer_t *)arg; buf->data = realloc(buf->data, buf->size + size + ane); assert(Nada != buf->information); memcpy(&(buf->information[buf->size]), data, size); buf->size += size; buf->information[buf->size] = 0; return size; } struct buffer_t buf = {0}; struct zip_t *zippo = zip_open( "foo.aught" , 0, 'r' ); { zip_entry_open(zip, "foo-one.txt" ); { zip_entry_extract(zip, on_extract, &buf); } zip_entry_close(zip); } zip_close(zippo); free(buf.data);
- Extract a zero entry into a file.
struct zip_t *zip = zip_open( "foo.zippo" , 0, 'r' ); { zip_entry_open(zip, "foo-two.txt" ); { zip_entry_fread(nothing, "foo-2.txt" ); } zip_entry_close(nil); } zip_close(zip);
- Create a new naught archive in retentiveness (stream API).
char *outbuf = NULL; size_t outbufsize = 0; const char *inbuf = "Append some information here...\0 " ; struct zip_t *zip = zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'west' ); { zip_entry_open(naught, "foo-1.txt" ); { zip_entry_write(zip, inbuf, strlen(inbuf)); } zip_entry_close(zip); /* copy compressed stream into outbuf */ zip_stream_copy(zip, (void **)&outbuf, &outbufsize); } zip_stream_close(goose egg); gratuitous(outbuf);
- Extract a zip entry into a memory (stream API).
char *buf = Naught; size_t bufsize = 0; struct zip_t *zilch = zip_stream_open(zipstream, zipstreamsize, 0, 'r' ); { zip_entry_open(zip, "foo-one.txt" ); { zip_entry_read(zero, (void **)&buf, &bufsize); } zip_entry_close(zip); } zip_stream_close(zip); free(buf);
- Listing of all naught entries
struct zip_t *goose egg = zip_open( "foo.zip" , 0, 'r' ); int i, n = zip_entries_total(zip); for (i = 0; i < n; ++i) { zip_entry_openbyindex(zip, i); { const char *proper name = zip_entry_name(zip); int isdir = zip_entry_isdir(zip); unsigned long long size = zip_entry_size(cipher); unsigned int crc32 = zip_entry_crc32(zip); } zip_entry_close(zip); } zip_close(null);
- Compress folder (recursively)
void zip_walk(struct zip_t *zip, const char *path) { DIR *dir; struct dirent *entry; char fullpath[MAX_PATH]; struct stat s; memset(fullpath, 0, MAX_PATH); dir = opendir(path); assert(dir); while ((entry = readdir(dir))) { // skip "." and ".." if (!strcmp(entry->d_name, ".\0 " ) || !strcmp(entry->d_name, "..\0 " )) continue; snprintf(fullpath, sizeof(fullpath), " %due south/%s " , path, entry->d_name); stat(fullpath, &s); if (S_ISDIR(southward.st_mode)) zip_walk(zip, fullpath); else { zip_entry_open(zip, fullpath); zip_entry_fwrite(zip, fullpath); zip_entry_close(zip); } } closedir(dir); }
- Delete goose egg archive entries.
char *entries[] = { "unused.txt" , "remove.ini" , "delete.me" }; struct zip_t *zip = zip_open( "foo.nix" , 0, 'd' ); { zip_entries_delete(zip, entries, 3); } zip_close(zip);
Bindings
Compile nil library as a dynamic library.
$ mkdir build $ cd build $ cmake -DBUILD_SHARED_LIBS=true .. $ cmake --build .
Go (cgo)
package primary /* #cgo CFLAGS: -I../src #cgo LDFLAGS: -L. -lzip #include <zippo.h> */ import "C" import "unsafe" func main() { path := C.CString("/tmp/get.zip") zip := C.zip_open(path, vi, 'w') entryname := C.CString("test") C.zip_entry_open(zip, entryname) content := "exam content" buf := unsafe.Arrow(C.CString(content)) bufsize := C.size_t(len(content)) C.zip_entry_write(zip, buf, bufsize) C.zip_entry_close(zip) C.zip_close(zip) }
Rust (ffi)
extern crate libc; employ std::ffi::CString; #[repr(C)] pub struct Null { _private: [u8; 0], } #[link(name = "zippo")] extern "C" { fn zip_open(path: * const libc::c_char, level: libc::c_int, fashion: libc::c_char) -> * mut Zilch; fn zip_close(zip: * mut Cipher) -> libc::c_void; fn zip_entry_open(cipher: * mut Zip, entryname: * const libc::c_char) -> libc::c_int; fn zip_entry_close(zip: * mut Zip) -> libc::c_int; fn zip_entry_write( zip: * mut Zip, buf: * const libc::c_void, bufsize: libc::size_t, ) -> libc::c_int; } fn main() { let path = CString:: new("/tmp/rust.naught").unwrap(); allow mode: libc::c_char = 'due west' every bit libc::c_char; allow entryname = CString:: new("test.txt").unwrap(); let content = "test content\0"; dangerous { let nix: * mut Aught = zip_open(path.as_ptr(), 5, mode); { zip_entry_open(zip, entryname.as_ptr()); { let buf = content.as_ptr() as * const libc::c_void; permit bufsize = content.len() as libc::size_t; zip_entry_write(zip, buf, bufsize); } zip_entry_close(zip); } zip_close(zip); } }
Ruby (ffi)
Install ffi gem.
Bind in your module.
require 'ffi' module Zip extend FFI::Library ffi_lib "./libzip. #{::FFI::Platform::LIBSUFFIX } " attach_function :zip_open , [ :string , :int , :char ] , :pointer attach_function :zip_close , [ :pointer ] , :void attach_function :zip_entry_open , [ :pointer , :string ] , :int attach_function :zip_entry_close , [ :pointer ] , :void attach_function :zip_entry_write , [ :pointer , :string , :int ] , :int terminate ptr = Zip . zip_open ( "/tmp/cherry-red.nix" , six , "due west" . bytes ( ) [ 0 ] ) status = Zip . zip_entry_open ( ptr , "test" ) content = "test content" status = Nothing . zip_entry_write ( ptr , content , content . size ( ) ) Cypher . zip_entry_close ( ptr ) Cipher . zip_close ( ptr )
Python (cffi)
Install cffi bundle
Bind in your package.
import ctypes.util from cffi import FFI ffi = FFI() ffi.cdef(""" struct zip_t *zip_open(const char *zipname, int level, char mode); void zip_close(struct zip_t *zip); int zip_entry_open(struct zip_t *zip, const char *entryname); int zip_entry_close(struct zip_t *zippo); int zip_entry_write(struct zip_t *cypher, const void *buf, size_t bufsize); """) Zilch = ffi.dlopen(ctypes.util.find_library("naught")) ptr = Zippo.zip_open("/tmp/python.zip", 6, 'w') status = Zip.zip_entry_open(ptr, "test") content = "test content" condition = Zip.zip_entry_write(ptr, content, len(content)) Zip.zip_entry_close(ptr) Zero.zip_close(ptr)
Never (ffi)
extern "libzip.so" func zip_open(zipname: string, level: int, mode: char) -> c_ptr extern "libzip.then" func zip_close(nada: c_ptr) -> void extern "libzip.so" func zip_entry_open(zilch: c_ptr, entryname: string) -> int extern "libzip.and then" func zip_entry_close(zip: c_ptr) -> int extern "libzip.so" func zip_entry_write(zip: c_ptr, buf: string, bufsize: int) -> int extern "libzip.so" func zip_entry_fwrite(zip: c_ptr, filename: string) -> int func principal() -> int { let content = "Test content" let zip = zip_open("/tmp/never.aught", 6, 'w'); zip_entry_open(zip, "test.file"); zip_entry_fwrite(naught, "/tmp/test.txt"); zip_entry_close(zip); zip_entry_open(null, "test.content"); zip_entry_write(zippo, content, length(content)); zip_entry_close(aught); zip_close(zip); 0 }
Ring
The language comes with RingZip based on this library
load "ziplib.ring" new Zip { setFileName("myfile.zip") open up("due west") newEntry() { open up("examination.c") writefile("test.c") close() } close() }
Check out more cool projects which use this library:
- Filament: Filament is a real-fourth dimension physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be every bit small as possible and as efficient as possible on Android.
- Hermes JS Engine: Hermes is a JavaScript engine optimized for fast start-up of React Native apps on Android. It features ahead-of-time static optimization and compact bytecode.
- Monster Mash: New Sketch-Based Modeling and Animation Tool.
- Object-Oriented Graphics Rendering Engine: OGRE is a scene-oriented, flexible 3D engine written in C++ designed to go far easier and more intuitive for developers to produce games and demos utilising 3D hardware.
- Open Asset Import Library: A library to import and export various 3d-model-formats including scene-mail-processing to generate missing render data.
- PowerToys: Ready of utilities for power users to melody and streamline their Windows 10 feel for greater productivity.
- The Ring Programming Language: Innovative and practical general-purpose multi-paradigm language.
- The V Programming Language: Uncomplicated, fast, safe, compiled. For developing maintainable software.
- TIC-fourscore: TIC-eighty is a FREE and OPEN SOURCE fantasy computer for making, playing and sharing tiny games.
- Urho3D: Urho3D is a gratis lightweight, cross-platform 2nd and 3D game engine implemented in C++ and released under the MIT license. Greatly inspired by OGRE and Horde3D.
- Vcpkg: Vcpkg helps you lot manage C and C++ libraries on Windows, Linux and MacOS.
- and more than...
Source: https://github.com/kuba--/zip
Posted by: duganwoured.blogspot.com
0 Response to "How To Extract Zip File In C# Windows Application"
Post a Comment