Если на сервер загружен большой zip-файл, и все, что вам нужно, это часть его содержимого, есть ли способ открыть его и выбрать то, что вы хотите загрузить?
Если на сервер загружен большой zip-файл, и все, что вам нужно, это часть его содержимого, есть ли способ открыть его и выбрать то, что вы хотите загрузить?
Ответы:
Я написал скрипт Python, list_remote_zip.py
который может перечислять файлы в виде zip-файла, доступного по HTTP:
import urllib2, struct, sys
def open_remote_zip(url, offset=0):
return urllib2.urlopen(urllib2.Request(url, headers={'Range': 'bytes={}-'.format(offset)}))
offset = 0
zipfile = open_remote_zip(sys.argv[1])
header = zipfile.read(30)
while header[:4] == 'PK\x03\x04':
compressed_len, uncompressed_len = struct.unpack('<II', header[18:26])
filename_len, extra_len = struct.unpack('<HH', header[26:30])
header_len = 30 + filename_len + extra_len
total_len = header_len + compressed_len
print('{}\n offset: {}\n length: {}\n header: {}\n payload: {}\n uncompressed length: {}'.format(zipfile.read(filename_len), offset, total_len, header_len, compressed_len, uncompressed_len))
zipfile.close()
offset += total_len
zipfile = open_remote_zip(sys.argv[1], offset)
header = zipfile.read(30)
zipfile.close()
Он не использует центральный каталог zip-файла, который находится в конце файла. Вместо этого он идет с самого начала и анализирует отдельные локальные заголовки и пропускает полезную нагрузку, надеясь получить другой заголовок. Он отправляет новый запрос каждый раз, когда ему нужно перейти к смещению. Это, конечно, работает только с серверами, которые поддерживают Range
заголовок HTTP.
Нужно только передать URL-адрес zip-файла в качестве аргумента командной строки. Пример использования и вывод должен выглядеть примерно так:
$ python list_remote_zip.py http://dl.xonotic.org/xonotic-0.8.1.zip
Xonotic/Makefile
offset: 0
length: 1074
header: 46
payload: 1028
uncompressed length: 5019
Xonotic/source/darkplaces/
offset: 1074
length: 56
header: 56
payload: 0
uncompressed length: 0
Xonotic/source/darkplaces/bih.h
offset: 1130
length: 1166
header: 61
payload: 1105
uncompressed length: 2508
Xonotic/source/darkplaces/portals.h
offset: 2296
length: 334
header: 65
payload: 269
uncompressed length: 648
...
Чтобы скачать один из файлов, я написал еще более get_file_from_remote_zip.sh
унылый скрипт bash, который использует wget
:
info=$(python list_remote_zip.py "$1" | grep -m 1 -A 5 "^$2\$" | tail -n +2)
tmpfile=$(mktemp)
wget --start-pos $(echo "$info" | grep offset | grep -o '[[:digit:]]*') -O - "$1" | head -c $(echo "$info" | grep -m 1 length | grep -o '[[:digit:]]*') >"$tmpfile"
printf '\x1f\x8b' # gzip magic
tail -c +9 <"$tmpfile" | head -c 1 # copy compression method
printf '\0\0\0\0\0\0\x03' # some flags and mtime
tail -c "+$(expr 1 + $(echo "$info" | grep header | grep -o '[[:digit:]]*'))" <"$tmpfile"
tail -c +15 <"$tmpfile" | head -c 4 # The CRCs seem to be compatible.
tail -c +23 <"$tmpfile" | head -c 4
rm "$tmpfile"
Требуется 2 аргумента. Первый - это URL-адрес zip-файла, а второй - извлекаемый файл. Имя файла, подлежащего извлечению, должно быть полным и в точности таким, каким оно отображается в выходных данных предыдущего list_remote_zip.py
скрипта Python, которые используются для получения некоторой информации о файле. Затем он использует его wget
для загрузки с правильным смещением и правильной длиной. Он сохраняет этот zip-фрагмент во временный файл, который затем используется для вывода gzip
отформатированного файла, который затем может быть передан по конвейеру и распакован gzip
. Сам по себе «фрагмент» не является допустимым zip-файлом, поскольку в его конце нет центрального каталога. Это можно исправить с помощью опции zip
's, -FF
но я решил вместо этого немного изменить заголовки и преобразовать их в файл gzip. алгоритм сжатия и даже контрольные суммы CRC-32 кажутся совместимыми.
Вот пример того, как загрузить случайный файл из архива Xonotic, доступного по адресу http://dl.xonotic.org/xonotic-0.8.1.zip , распаковать его и сохранить в локальном файле:
bash get_file_from_remote_zip.sh http://dl.xonotic.org/xonotic-0.8.1.zip Xonotic/source/darkplaces/mprogdefs.h | gzip -d >mprogdefs.h
list_remote_zip.py
. Поэтому, если у вас установлен Python, вы можете запустить его и передать URL-адрес zip-файла в качестве аргумента командной строки следующим образом: python list_remote_zip.py http://dl.xonotic.org/xonotic-0.8.1.zip
Предполагая, что сервер поддерживает возобновленные загрузки, теоретически можно было бы написать клиента, который сделал это - захватить достаточно большой блок в конце, чтобы получить каталог, а затем использовать его, чтобы выяснить, что вам нужно захватить, чтобы получить данные. - просто начните загрузку с этой позиции и остановитесь, когда у вас будет достаточно данных. Прошло так много времени с тех пор, как я копался, я не помню, есть ли способ найти начало каталога, кроме грубой силы.
Я никогда не слышал о таком клиенте и не могу себе представить, почему он будет разработан - если это данные, которые разумно будут загружаться по частям, то почему веб-мастер хранит их как один большой zip-файл ???
rar x --kb myincompletefile.rar
. Ибо7zip
увидеть даже этот ответ . Какой тип сервера вы имеете в виду? Вы используетеzip
просто сказать сжатый или вы ссылаетесь строго наzip
файлы?