오프셋을 사용하여 부분적으로 다운로드된 gzip 읽기

오프셋을 사용하여 부분적으로 다운로드된 gzip 읽기

엄청난 일이 있다고 가정해보자db.sql.gz사용 가능한 크기 100GB https://example.com/db/backups/db.sql.gz및 서버 지원범위 요청.

그래서 다운로드한 전체 파일을 다운로드하는 대신y오프셋이 있는 바이트(1024바이트라고 가정)x바이트(1000바이트로 가정)는 다음과 같습니다.

curl -r 1000-2024 https://example.com/db/backups/db.sql.gz

위의 명령을 사용하여 gzip 압축 파일의 일부를 다운로드할 수 있었습니다. 이제 해당 부분을 어떻게 읽을 수 있는지 궁금합니다.

시도했지만 gunzip -c db.sql.gz | dd ibs=1024 skip=0 count=1 > o.sql오류가 발생했습니다.

gzip: dbrange.sql.gz: gzip 형식이 아님

인코딩을 설명하는 파일 상단에 헤더 블록이 있을 수 있다고 추측하기 때문에 오류는 허용됩니다.


오프셋 없이 파일을 다운로드하면 gunzip파이프를 사용하여 파일을 읽을 수 있다는 것을 알았습니다.

curl -r 0-2024 https://example.com/db/backups/db.sql.gz

답변1

그냥 FWIW,이전에는 gzip에 무작위로 액세스할 수 있습니다.색인파일이 생성되었습니다...

인덱스가 제공되면 gzip에 대한 빠르고 (거의) 무작위 액세스를 제공하는 명령줄 도구를 개발했습니다(그렇지 않은 경우 자동으로 생성됨).

https://github.com/circulosmeos/gztool

gztool청크가 인덱스가 가리키는 특정 바이트 지점(물론 gzip은 바이트가 아닌 비트스트림이므로 -1 바이트)에서 검색된 경우 원본 gzip 파일의 청크에 액세스하는 데 사용할 수 있습니다. 그들의 후.

예를 들어인덱스 포인트가 시작되는 경우( gztool -ll index.gzi이 데이터 제공) 바이트 압축1508611파일의 gzip 부분, 그 이후에는 1M 압축 바이트가 필요합니다.

$ curl -r 1508610-2508611 https://example.com/db/backups/db.sql.gz > chunk.gz
  • chunk.gz디스크의 블록 크기만 차지한다는 점에 유의하세요 !
  • 또한 그러하다는 점도 참고하세요아니요불완전하기 때문에 유효한 gzip 파일입니다.
  • 또한 원하는 인덱스 포인트 위치에서 1바이트 적게 검색했다는 점을 고려하세요.

이제 전체 인덱스도 검색해야 합니다(예: gztool -i *.gz모든 gzip 압축 파일 인덱싱 또는 gztool -c *압축 및 인덱싱 등 이전에는 한 번만 생성됨). 인덱스는 gzip 크기의 약 0.3%입니다( gztool데이터 자체가 압축되면 인덱스가 훨씬 작아집니다).

$ curl https://example.com/db/backups/db.sql.gzi -o chunk.gzi

이제 다음을 통해 추출을 수행할 수 있습니다.격자 도구. 해당 압축되지 않은 압축 바이트 1508610(또는 이를 전달하는 바이트)을 알아야 하지만 인덱스를 사용할 수 있습니다 gztool -ll.여기 예. 바이트 9009009라고 가정해 보겠습니다. 또는 우리가 원하는 압축되지 않은 바이트는 단순히 Chunk.gz에 포함된 해당 첫 번째 인덱스 포인트로 전달됩니다. 이 경우 바이트도 9009009라고 다시 가정해 보겠습니다.

$ gztool -n 1508610 -b 9009009 chunk.gz > extracted_chunk.sql

gztoolchunk.gz파일이 끝나면 데이터 추출이 중지됩니다.

까다로울 수 있지만 압축 방법이나 이미 압축된 파일을 변경하지 않고도 실행할 수 있습니다. 하지만 색인을 생성해야 합니다.


노트:매개변수 없이 추출하는 또 다른 방법은 -ngzip 파일을 다음으로 채우는 것입니다.부족한Zero: 예제에서는 다음 dd명령을 통해 수행 됩니다.앞으로첫 번째는 파일을 curl검색하는 데 사용됩니다 . 따라서 다음과 같습니다.chunk.gz

$ dd if=/dev/zero of=chunk.gz seek=1508609 bs=1 count=0
$ curl -r 1508610-2508611 https://example.com/db/backups/db.sql.gz >> chunk.gz
$ curl https://example.com/db/backups/db.sql.gzi -o chunk.gzi

이런 식으로 파일의 처음 1508609바이트는 0이고,하지만 디스크 공간을 차지하지 않습니다.. seekin 명령이 없으면 dd0이 모두 디스크에 기록되며 이는 에서도 작동 gzip하지만 이 방법으로 디스크에서 불필요한 공간을 차지하지 않습니다. 그러면 gztool 명령에는 이 -n매개변수가 필요하지 않습니다. 인덱스가 존재할 때 gztool압축되지 않은 9009009 바이트 위치 이전의 인덱스 포인트로 점프하는 데 사용되므로 이전 데이터는 모두 무시되므로 0으로 지정된 데이터는 필요하지 않습니다.

$ gztool -b 9009009 chunk.gz > extracted_chunk.sql

답변2

gzip블록 압축 파일은 생성되지 않습니다.RFC자세한 내용은) 본질적으로 무작위 액세스에 적합하지 않습니다. 스트림에서 데이터 읽기를 시작하고 언제든지 중지할 수 있으므로 예제가 curl -r 0-2024작동하지만 누락된 데이터(예: 인덱스 파일)를 제공하는 추가 파일이 없으면 중간에 스트림을 가져올 수 없습니다. ... 만들다gztool).

원하는 것을 달성하려면 특정 유형의 블록 압축을 사용해야 합니다.예를 들어 bgzip(일반으로 압축을 풀 수 있는 파일을 생성합니다 gzip) 또는bzip2, 수신 측에서 몇 가지 작업을 수행하여 블록 경계가 어디에 있는지 확인합니다. Peter Cock은 이 주제에 관해 몇 가지 흥미로운 기사를 썼습니다:BGZF - 차단되고, 더 크고, 더 나은 GZIP!,BZIP2에 대한 무작위 액세스?

관련 정보