2012-07-06 26 views
8

Tôi đang cố gắng lưu trữ các tệp cho một ứng dụng đa nền tảng và có vẻ như Minizip (được xây dựng trên zlib) có tính di động như các trình lưu trữ đến.Làm cách nào để sử dụng Minizip (trên Zlib)?

Khi tôi cố gắng chạy mã giả sau đây, tuy nhiên, tôi nhận được một lỗi hệ thống [my executable] has stopped working. Windows can check online for a solution to the problem.

bất cứ ai có thể giúp tôi xem làm thế nào để sử dụng thư viện này? — (không có doc hay hướng dẫn bất cứ nơi nào mà tôi có thể tìm thấy)

zip_fileinfo zfi; 

int main() 
{ 
    zipFile zf = zipOpen("myarch.zip",APPEND_STATUS_ADDINZIP); 
    int ret = zipOpenNewFileInZip(zf, 
     "myfile.txt", 
     &zfi, 
     NULL, 0, 
     NULL, 0, 
     "my comment for this interior file", 
     Z_DEFLATED, 
     Z_NO_COMPRESSION 
     ); 
    zipCloseFileInZip(zf); 
    zipClose(zf, "my comment for exterior file"); 
    return 0; 
} 

Specs: MSYS + MinGW, Windows 7, sử dụng zlibwapi.dll từ zlib125dll.zip/dll32

Trả lời

16

Vì tôi đã tìm thấy câu hỏi này thông qua Google và nó không chứa bất kỳ mã làm việc hoàn chỉnh nào, tôi đang cung cấp một số ở đây cho khách truy cập trong tương lai.

int CreateZipFile (std::vector<wstring> paths) 
{ 
    zipFile zf = zipOpen(std::string(destinationPath.begin(), destinationPath.end()).c_str(), APPEND_STATUS_CREATE); 
    if (zf == NULL) 
     return 1; 

    bool _return = true; 
    for (size_t i = 0; i < paths.size(); i++) 
    { 
     std::fstream file(paths[i].c_str(), std::ios::binary | std::ios::in); 
     if (file.is_open()) 
     { 
      file.seekg(0, std::ios::end); 
      long size = file.tellg(); 
      file.seekg(0, std::ios::beg); 

      std::vector<char> buffer(size); 
      if (size == 0 || file.read(&buffer[0], size)) 
      { 
       zip_fileinfo zfi = { 0 }; 
       std::wstring fileName = paths[i].substr(paths[i].rfind('\\')+1); 

       if (S_OK == zipOpenNewFileInZip(zf, std::string(fileName.begin(), fileName.end()).c_str(), &zfi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION)) 
       { 
        if (zipWriteInFileInZip(zf, size == 0 ? "" : &buffer[0], size)) 
         _return = false; 

        if (zipCloseFileInZip(zf)) 
         _return = false; 

        file.close(); 
        continue; 
       } 
      } 
      file.close(); 
     } 
     _return = false; 
    } 

    if (zipClose(zf, NULL)) 
     return 3; 

    if (!_return) 
     return 4; 
    return S_OK; 
} 
+0

Điều này là tốt. Một vài vấn đề mặc dù: 1. Điều này giả định rằng toàn bộ tập tin có thể phù hợp với bộ nhớ, đó là một cái nhìn đơn giản, nhưng có lẽ đủ tốt cho mẫu này. 2. Không có lý do tại sao một đầu ra tập tin chiều dài 0 là một lỗi nếu chiều dài tập tin ban đầu là 0. 3. Giả sử rằng đó là một lỗi, không cần cho hoạt động ba giây. tức là 'if (zipWriteInFileInZip (zf, size == 0?" ": & buffer [0], size))' có thể được viết dưới dạng 'if (zipWriteInFileInZip (zf, & buffer [0], size))'. 4. Tôi khuyên bạn không nên sử dụng tiền tố gạch dưới. Tôi biết bạn đang sử dụng một chữ thường sau nó, nhưng ... * nhún vai * – Adrian

+0

Điểm thứ hai và thứ ba bạn nâng cao là sai. Kích thước == 0 kiểm tra là để đảm bảo rằng bộ đệm [0] không được thực hiện trên độ dài bằng không. Phép logic hoặc hoạt động trong câu lệnh if sau đó đảm bảo rằng các tệp có độ dài bằng không được ghi vào tệp zip một cách chính xác, và sau đó một lần nữa, để đảm bảo rằng bộ đệm [0] không được gọi trên độ dài 0. Mã hoạt động chính xác và như mong đợi. – niemiro

+0

Thẻ này được gắn thẻ là C chứ không phải C++. –

2

Các lib minizip là tốt tài liệu. Chỉ cần mở zip.h để biết chi tiết.

Tôi có thể cho bạn biết ở đây, bạn có thể đã truyền thông số sai cho zipOpen. (APPEND_STATUS_ADDINZIP yêu cầu tệp zip hiện tại!)

Ngoài ra, hãy kiểm tra xem zipOpen có trả về một trình xử lý zipFile hợp lệ hay không.

+0

Cảm ơn. Tôi đã thay đổi arg thứ 2 của mình thành 'APPEND_STATUS_CREATE'. Tôi không thấy bất kỳ tham chiếu nào về tính hợp lệ trong zip.h; cho rằng, tôi nên chỉ kiểm tra xem zipfile là 'NULL'? – JellicleCat

+0

Ngoài ra, bạn có thể làm sáng tỏ những gì 'extrafield_local' và' extrafield_global' được cho là phải không? Tôi không tìm thấy bất kỳ ví dụ hoặc mô tả đầy đủ nào. – JellicleCat

+0

Tôi chưa bao giờ sử dụng extrafield_local và extrafield_global trước đây. Xin lỗi tôi không thể giúp. Nếu zip.h của bạn không chứa tài liệu, bạn có thể tải xuống mã nguồn zlib. Tôi chắc chắn zip.h trong gói đó chứa tài liệu tốt. – Rango

3

Thư viện minizip không có ví dụ; minizip.c để nén và miniunz.c để giải nén. Cả hai đều là tiện ích dòng lệnh hiển thị cách sử dụng thư viện. Họ là một mớ hỗn độn mặc dù.

Bạn cũng cần điền vào zfi zip_fileinfo. Ít nhất bạn nên khởi tạo cấu trúc bằng không. zfi chứa thông tin về tệp bạn muốn lưu trữ bằng cách sử dụng zipOpenNewFileInZip. Cấu trúc phải chứa ngày và thuộc tính của "myfile.txt".

Tôi khuyên bạn nên sử dụng PKWARE Desktop để chẩn đoán sự cố về zip. Nó cho thấy cấu trúc/thuộc tính của các tệp trong ZIP và bản thân tệp ZIP. Khi tôi mở myarch.zip nó nói với tôi rằng có lỗi. Tôi đã đi sâu vào các thuộc tính của tệp và thấy rằng các thuộc tính đã bị tắt.

+1

Cảm ơn bạn đã điều tra, nhưng trong mẫu mã ở trên, không nên 'zfi' được khởi tạo bằng không nếu không có tôi chỉ định nó? Đó là trên đống kể từ khi nó ở bên ngoài của bất kỳ chức năng, phải không? – JellicleCat

+0

À vâng, bạn đúng. Tôi vừa ném mã của bạn vào một hàm để xem nó có hoạt động không. –

+1

Mã của bạn sẽ hoạt động bình thường sau đó. Tôi đã không nhận được bất kỳ Windows bị treo từ nó. Nó có thể là một vấn đề với việc sử dụng DLL. Bạn đã thử biên dịch trong thư viện zlib chưa? –

Các vấn đề liên quan