2014-05-22 2 views
0

일부 데이터를 압축하려고하지만 여러 개의 아카이브로 데이터 세트를 분할하여 단일 zip 파일이 최대 값보다 커지지 않도록하십시오.주어진 크기에 도달 할 때까지 zip 아카이브에 데이터를 추가하십시오.

내 데이터가 파일 시스템의 소스가 아니기 때문에 스트리밍 방식을 사용하는 것이 좋습니다. 각 조각을 쓰기 전에 스트림 위치를 추적하면서 한 번에 하나의 원자 조각을 쓸 수 있다고 생각했습니다. 한도를 초과하면 적합하지 않은 부분을 작성하기 전에 위치로 스트림을 잘라내어 다음 보관 파일을 만듭니다.

System.IO.Compression의 클래스로 시도했습니다. 아카이브를 만들고, 항목을 만들고, ZipArchiveEntry.Open을 사용하여 스트림을 가져 와서 해당 스트림에 씁니다. 문제는 아카이브가 어느 시점에서 얼마나 큰지 알 수 없다는 것입니다.

스트림의 위치를 ​​읽을 수 있지만 압축되지 않은 바이트를 추적하고 있습니다. 스트림을 자르면 잘 작동하므로 압축 된 아카이브의 크기가 아니라 아카이브 당 압축되지 않은 데이터의 양에 제한이 적용된다는 중요한 예외가있는 지금 의도 된대로 작동합니다.

데이터는 압축 가능한 일부 텍스트이고 다양한 압축 형식 (최종 사용자의 첨부 파일)은 때로는 매우 압축 적이며 때로는 전혀 압축되지 않을 수도 있습니다.

내 질문 :

1) 본질적으로 내 접근와 충돌 폐의 알고리즘에 대해 뭔가가 있나요? 나는 이것이 블록 기반의 압축 스키마라는 것을 알고 있으며 알고리즘은 전체 아카이브이 지정 될 때까지 압축 된 데이터를 인코딩하는 방법을 결정할 수 없다고 상상합니다.

2) 위의 (1)에 대한 대답이 "예"이면 오버 헤드가 너무 많이 발생하지 않는 좋은 전략은 무엇입니까?

내가 가진 한 가지 생각은 압축 된 데이터가 압축되지 않은 데이터보다 클 수 없다고 가정하는 것입니다. 압축되지 않은 데이터가 임계 값을 초과 할 때까지 스트림에 기록한 다음 아카이브를 저장하고 임계 값과 현재 크기의 차이를 계산 한 다음 전체가 될 때까지 반복 할 수 있습니다.

명확하지 않은 경우 제한이 1MB라고 가정합니다. 1MB의 압축되지 않은 데이터를 작성하고 아카이브를 저장합니다. 그런 다음 결과 아카이브가 0.3MB임을 확인합니다. 필자는 압축 파일 (및 해당 항목 만)을 다시 열고 0.7MB의 새로운 제한으로 다시 시작합니다. 왜냐하면 오버 슈팅없이 압축되지 않은 많은 데이터를 추가 할 수 있다는 것을 알고 있기 때문입니다. 이 접근 방식은 구현하기가 상대적으로 간단하고 테스트 할 것이지만 누군가가 더 좋은 아이디어를 갖고 있는지 듣고 싶습니다.

답변

0

FileStreamLength 또는 Position을 보면 압축 된 데이터의 크기가 얼마인지를 알 수 있습니다. 그런 다음 항목 추가를 중지 할 수 있습니다. ZIP 스트림 클래스는 너무 많이 버퍼링하지 않는 경향이 있습니다. 아마도 64KB 정도 될 것입니다.

특정 시점에서 아카이브를 잘라낼 수 있어야합니다. 기본 스트림 Position을 측정하기 전에 ZIP 스트림을 플러시하십시오. 이것은 이론 상으로는 항상 가능하지만 사용중인 실제 라이브러리가이를 지원하지 않을 수 있습니다. 그것을 테스트하거나 소스를보십시오.

+0

감사합니다. 전체 아카이브 (zip에서 하나 또는 여러 항목이 있는지 여부)가 닫힐 때까지 기본 스트림에 아무 것도 쓰지 않습니다. 디버거에서 그것을보고, 스트림은 ZipArchiveEntry에서 반환했습니다.Open은 MemoryStream을 기본 스트림으로 사용합니다. 스트림에 쓸 때마다 내가 입력 * 버퍼를 채우는 것과 같습니다. 실제로 아카이브가 닫힐 때까지 실제 압축이 발생하지 않습니다. 내가 사용하고있는 라이브러리는 .NET Framework 4.5 (System.IO.Compression 네임 스페이스)입니다. :) –

+0

좋아, 나는 그 BCL 기능에 대해 많이 모른다. 하지만 .NET 4.0에서 끔찍한 압축을 겪었습니다. 어쩌면 여전히. SharpZipLib과 같은 더 나은 라이브러리를 사용하십시오. 전체 아카이브를 버퍼링하지 않습니다. ZIP은 단색 형식이 아닙니다. 버퍼링 할 필요가 없습니다 (많이). – usr

관련 문제