2012-03-04 8 views
1

로컬 SQLite 데이터베이스를 사용하는 Windows Phone 7 프로젝트를 개발 중입니다. 데이타베이스는 압축되지 않은 ~ 40MB이므로 최대 압축 (압축)을 사용하여 ~ 20MB까지 압축했습니다. 여기에 내 코드가있다.Windows Phone 7에서 LZMA 압축 zip 파일을 압축 해제하는 방법은 무엇입니까?


    private void unzip_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = (BackgroundWorker)sender; 
     IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication(); 
     IsolatedStorageFileStream file = new IsolatedStorageFileStream(filename, FileMode.Create, store); 
     // TODO: switch from Deflate ~18.7MB to LZMA ~12.1MB (original ~41.5MB) 
     StreamResourceInfo zipInfo = new StreamResourceInfo((Stream)e.Argument, null); 
     StreamResourceInfo streamInfo = Application.GetResourceStream(zipInfo, new Uri(filename, UriKind.Relative)); 
     long total = streamInfo.Stream.Length; 
     long done = 0; 
     int size = 32768; 
     byte[] data = new byte[size]; 
     while ((size = streamInfo.Stream.Read(data, 0, data.Length)) > 0) 
     { 
      file.Write(data, 0, size); 
      done += size; 
      int percentComplete = (int)(100 * ((float)done/(float)total)); 
      worker.ReportProgress(percentComplete); 
     } 
     file.Close(); 
    } 

20메가바이트 좋은 개선하지만 최대 압축 (LZMA)를 사용하여 7Z 아카이브 ~ 12메가바이트의 파일 크기를 얻을 것으로 나타났습니다. zip 파일 형식은 LZMA 내용을 지원하므로 LZMA 압축 zip 파일의 Deflate 압축 zip 파일을 전환하고 bang을 전환했습니다. 내가 얻을 NullReferenceException : Application.GetResourceStream(...) null을 반환합니다. 아마도 그 구현은 LZMA 콘텐츠를 처리하지 못할 것입니다.

다른 라이브러리를 사용해 보았지만 Deflated zip에서 제대로 작동했지만 LZMA zip (NotSupportedException : 압축 방법이 지원되지 않음)에서 다시 실패합니다.


    using ICSharpCode.SharpZipLib.Zip; 
    ... 
    private void unzip_DoWork(object sender, DoWorkEventArgs e) 
    { 
    ... 
     using (ZipInputStream zip = new ZipInputStream((Stream)e.Argument)) 
     { 
      ZipEntry entry = zip.GetNextEntry(); // consume zip header (required) 
      .... 
     } 
    } 

내가 NuGet에서 보면서 LZMA 압축 해제를 지원하기 위해 주장 약간의 C# 라이브러리가 있지만, 그들은 내 Windows Phone 프로젝트와 호환되지 있었다 (나는 .NET3 또는 위해 설정 된 때문에 생각합니다. NET4는 아니지만 .NET 3.5).

LZMA SDK를 사용하여 ICSharpCode.SharpZipLib.LZMA 클래스를 구현할 생각이 들었지만 바퀴를 다시 만들기 전에 누군가 Windows Phone에서 LZMA zip을 성공적으로 압축 해제했는지 묻는 것이 좋습니다.

도움을 주시면 감사하겠습니다.

답변

1

LZMA 압축 풀기의 Windows Phone 구현을 계속했지만 행운은 없었으므로 LZMA SDK 버전 9.22 베타를 기반으로 만들었습니다. 누군가가 유용하다고 생각하면 여기에 세부 정보를 게시하십시오 (물론 보증은 없습니다).

프로젝트 소스는 여기에서 찾을 수 있습니다 :합니다 (SDK에서)

  1. StreamDecoderSevenZip.Compression.LZMA.Decoder과 : 이 https://github.com/larryk78/SevenZip.Compression.LZMA.WindowsPhone/

    구현은 세 가지 압축 해제 시나리오 (나는 아직, 압축 보지 않았다)를 제공 스트림 - 스트림 복원을 제공합니다.

  2. IsolatedStorageDecoder을 확장하면 IsolatedStorage의 스트림이나 파일에서 IsolatedStorage의 파일로 압축을 풀 수 있습니다. 즉 스트림 - 투 - 파일 및 파일 - 투 - 파일이다.
  3. WebClient2IsolatedStorageDecoderIsolatedStorageDecoder을 확장하여 Uri에서 압축 파일을 다운로드 한 다음 IsolatedStorage의 파일로 압축을 푸십시오.

N.B. StreamDecoderBackgroundWorker으로 구현되므로 압축 해제 작업이 비동기 적으로 완료되며 (UI 스레드를 차단하지 않음) 진행률을 ProgressBar에 연결할 수 있습니다.

여기 WebClient2IsolatedStorageDecoder를 사용하는 예제입니다 :

using SevenZip.Compression.LZMA.WindowsPhone; 
using System.ComponentModel; 

// <Button Content="Click Me!" Click="button_Click" /> 
private void button_Click(object sender, RoutedEventArgs e) 
{ 
    WebClient2IsolatedStorageDecoder decoder = new WebClient2IsolatedStorageDecoder(); 
    decoder.ProgressChanged += new ProgressChangedEventHandler(decoder_ProgressChanged); 
    decoder.RunWorkerCompleted += new RunWorkerCompletedEventHandler(decoder_RunWorkerCompleted); 
    decoder.DecodeAsync(new Uri("http://example.com/compressed_file.lzma"), "decompressed_file.txt"); 
} 

void decoder_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    // <ProgressBar x:Name="Progress" /> 
    Progress.Value = e.ProgressPercentage; 
} 

void decoder_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error) 
    { 
     MessageBox.Show("Couldn't download/decompress: " + e.Error.Message); 
     return; 
    } 

    // ...do something with the decompressed data :) 
} 

당신이 그것을 시도하는 경우 알려 주시기 바랍니다.아주 실제 사용자 ™ 피드백 :

건배, 래리

P.S.처럼 아무것도 없습니다 이 라이브러리는 * .zip 파일을 처리하지 않습니다. LZMA 압축 파일, 즉 * .lzma에서 작동합니다. LZMA SDK의 lzma.exe를 사용하여이 작업을 수행 할 수 있습니다 (바이너리도 위에 링크 된 github 저장소에 있음). LZMA를 통합하는 ICSharpCode.SharpZipLib 라이브러리의 관리자와 이야기를 나누었습니다. 그곳에서 무슨 일이 일어나는지 보도록하겠습니다.