код iPhone Unzip

Копирование elision - это метод оптимизации компилятора, который устраняет ненужное копирование / перемещение объектов.

В следующих случаях компилятору разрешено пропускать операции копирования / перемещения и, следовательно, не вызывать связанный конструктор:

  1. NRVO (Именованная оптимизация возвращаемого значения): If функция возвращает тип класса по значению, а выражение оператора return - это имя энергонезависимого объекта с автоматическим временем хранения (который не является параметром функции), а затем копирование / перемещение, которое будет выполняться не оптимизирующим компилятор может быть опущен. Если это так, возвращаемое значение создается непосредственно в хранилище, к которому в противном случае возвращаемое значение функции было бы перемещено или скопировано.
  2. RVO (Оптимизация возвращаемого значения): если функция возвращает неназванный временный объект, который будет перемещен или скопирован в место назначения наивным компилятором, копия или перемещение могут быть опущены в соответствии с 1.
#include <iostream>  
using namespace std;

class ABC  
{  
public:   
    const char *a;  
    ABC()  
     { cout<<"Constructor"<<endl; }  
    ABC(const char *ptr)  
     { cout<<"Constructor"<<endl; }  
    ABC(ABC  &obj)  
     { cout<<"copy constructor"<<endl;}  
    ABC(ABC&& obj)  
    { cout<<"Move constructor"<<endl; }  
    ~ABC()  
    { cout<<"Destructor"<<endl; }  
};

ABC fun123()  
{ ABC obj; return obj; }  

ABC xyz123()  
{  return ABC(); }  

int main()  
{  
    ABC abc;  
    ABC obj1(fun123());//NRVO  
    ABC obj2(xyz123());//NRVO  
    ABC xyz = "Stack Overflow";//RVO  
    return 0;  
}

**Output without -fno-elide-constructors**  
root@ajay-PC:/home/ajay/c++# ./a.out   
Constructor    
Constructor  
Constructor  
Constructor  
Destructor  
Destructor  
Destructor  
Destructor  

**Output with -fno-elide-constructors**  
root@ajay-PC:/home/ajay/c++# g++ -std=c++11 copy_elision.cpp -fno-elide-constructors    
root@ajay-PC:/home/ajay/c++# ./a.out   
Constructor  
Constructor  
Move constructor  
Destructor  
Move constructor  
Destructor  
Constructor  
Move constructor  
Destructor  
Move constructor  
Destructor  
Constructor  
Move constructor  
Destructor  
Destructor  
Destructor  
Destructor  
Destructor  

Даже когда происходит копирование и конструктор copy / move (как будто никакой оптимизации вообще не было), в противном случае программа плохо сформирована.

Вы должны разрешить такое копирование только в тех местах, где это не повлияет наблюдаемое поведение вашего программного обеспечения. Копирование elision - единственная форма оптимизации, которая позволяет иметь (то есть elide) наблюдаемые побочные эффекты. Пример:

#include <iostream>     
int n = 0;    
class ABC     
{  public:  
 ABC(int) {}    
 ABC(const ABC& a) { ++n; } // the copy constructor has a visible side effect    
};                     // it modifies an object with static storage duration    

int main()   
{  
  ABC c1(21); // direct-initialization, calls C::C(42)  
  ABC c2 = ABC(21); // copy-initialization, calls C::C( C(42) )  

  std::cout << n << std::endl; // prints 0 if the copy was elided, 1 otherwise
  return 0;  
}

Output without -fno-elide-constructors  
root@ajay-PC:/home/ayadav# g++ -std=c++11 copy_elision.cpp  
root@ajay-PC:/home/ayadav# ./a.out   
0

Output with -fno-elide-constructors  
root@ajay-PC:/home/ayadav# g++ -std=c++11 copy_elision.cpp -fno-elide-constructors  
root@ajay-PC:/home/ayadav# ./a.out   
1

GCC предоставляет возможность -fno-elide-constructors отключить копирование. Если вы хотите избежать возможного копирования, используйте -fno-elide-constructors.

Теперь почти все компиляторы обеспечивают копирование при разрешении оптимизации (и если для его отключения не установлен другой параметр).

Заключение

С каждым экземпляром копии исключается одна конструкция и одно совпадение с уничтожением копии, что позволяет сэкономить время процессора, а один объект не создан, что позволяет сэкономить место в стеке кадр.

26
задан Cœur 20 July 2017 в 12:35
поделиться

7 ответов

"sample.zip" был действительно создан с gZip? .zip расширение обычно используется для архивов, созданных WinZip. Те могут также быть распакованы с помощью zLib, но необходимо было бы проанализировать заголовок и использовать другие стандартные программы.

Для проверки взгляните на первые два байта файла. Если это - 'PK', это - WinZip, если это - 0x1F8B, это - gZip.

, поскольку это - конкретный iPhone, взгляните на этот обсуждение форума iPhone SDK , где мини-zip упоминается. Кажется, что это может обработать файлы WinZip.

, Но если это - действительно файл WinZip, необходимо взглянуть на спецификация WinZip и попытка проанализировать файл сами. Это в основном должно анализировать некоторые значения заголовка, ища сжатое потоковое положение и с помощью zLib стандартные программы для распаковки его.

13
ответ дан schnaader 28 November 2019 в 06:31
поделиться

Действительно трудно разархивировать любой произвольный zip-файл. Это - сложный формат файла, и существует потенциально много различных стандартных программ сжатия, которые, возможно, привыкли внутренне к файлу. Информационный ZIP имеет некоторый свободно licencable код, чтобы сделать это ( http://www.info-zip.org/UnZip.html ), который может быть сделан работать над iPhone с некоторым взламыванием, но API откровенно ужасен - это включает передающие параметры командной строки к фальшивке, 'основной', который моделирует выполнение UnZIP (чтобы быть справедливым поэтому, что их код никогда не разрабатывался, чтобы использоваться как это во-первых, функциональность библиотеки была соединена болтом на впоследствии).

, Если Вы имеете какой-либо контроль над тем, где файлы Вы пытаетесь разархивировать, прибывают из, я высоко рекомендую использовать другую систему сжатия вместо ZIP. Это - гибкость, и повсеместность делают его большим для того, чтобы раздать архивы файлов в от человека к человеку, но это очень неудобно автоматизировать.

1
ответ дан th_in_gs 28 November 2019 в 06:31
поделиться

zlib не предназначен для открытия .zip файлов, но Вы находитесь в удаче: contrib каталог zlib включает мини-zip, которая в состоянии использовать zlib для открытия .zip файлов.

Это не может быть связано в SDK, но можно, вероятно, использовать комплектную версию zlib, используют его. Захватите копию zlib источника и взгляда в contrib/minizip.

1
ответ дан Jeff M 28 November 2019 в 06:31
поделиться

Я не использовал iPhone, но можно хотеть посмотреть GZIP, который является очень портативной библиотекой zip с открытым исходным кодом, доступной для многих платформ.

0
ответ дан SmacL 28 November 2019 в 06:31
поделиться

Этот код хорошо работал у меня для gzip:

база данных была подготовлена ​​следующим образом: gzip foo.db

ключ перебирал gzread (). В приведенном выше примере считываются только первые байты CHUNK.

#import <zlib.h>
#define CHUNK 16384


  NSLog(@"testing unzip of database");
  start = [NSDate date];
  NSString *zippedDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"foo.db.gz"];
  NSString *unzippedDBPath = [documentsDirectory stringByAppendingPathComponent:@"foo2.db"];
  gzFile file = gzopen([zippedDBPath UTF8String], "rb");
  FILE *dest = fopen([unzippedDBPath UTF8String], "w");
  unsigned char buffer[CHUNK];
  int uncompressedLength;
  while (uncompressedLength = gzread(file, buffer, CHUNK) ) {
    // got data out of our file
    if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
      NSLog(@"error writing data");
    }
  }
  fclose(dest);
  gzclose(file);
  NSLog(@"Finished unzipping database");

Между прочим, я могу распаковать 33 МБ в 130 МБ за 77 секунд или около 1,7 МБ без сжатия в секунду.

12
ответ дан 28 November 2019 в 06:31
поделиться

Мне повезло, тестируя это на симуляторе iPhone:

NSArray *paths = 
   NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *saveLocation = 
   [documentsDirectory stringByAppendingString:@"myfile.zip"];

NSFileManager* fileManager = [NSFileManager defaultManager];

if ([fileManager fileExistsAtPath:saveLocation]) {
    [fileManager removeItemAtPath:saveLocation error:nil];

}

NSURLRequest *theRequest = 
             [NSURLRequest requestWithURL:
                [NSURL URLWithString:@"http://example.com/myfile.zip"]
             cachePolicy:NSURLRequestUseProtocolCachePolicy
             timeoutInterval:60.0];    

NSData *received = 
             [NSURLConnection sendSynchronousRequest:theRequest 
                              returningResponse:nil error:nil];    

if ([received writeToFile:saveLocation atomically:TRUE]) {      
    NSString *cmd = 
       [NSString stringWithFormat:@"unzip \"%@\" -d\"%@\"", 
       saveLocation, documentsDirectory];       

    // Here comes the magic...
    system([cmd UTF8String]);       
}

Это выглядит проще, чем возиться с zlib ...

-4
ответ дан 28 November 2019 в 06:31
поделиться

Мне нужно было простое решение, но я не нашел здесь того, что мне понравилось бы, поэтому я изменил библиотеку, чтобы делать то, что я хотел. Вы можете найти SSZipArchive полезным. (Кстати, он также может создавать zip-файлы.)

Использование:

NSString *path = @"path_to_your_zip_file";
NSString *destination = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:path toDestination:destination];
41
ответ дан 28 November 2019 в 06:31
поделиться