2 votes

Existe-t-il un moyen de télécharger des parties du contenu d'un fichier zip ?

Si un gros fichier zip est téléchargé sur un serveur et que vous n'avez besoin que d'une partie de son contenu, existe-t-il un moyen de l'ouvrir et de choisir ce que vous voulez télécharger ?

0 votes

La question est donc vraiment générique, mais généralement pas. Avec certains formats compressés, vous pouvez être en mesure d'extraire une partie de leur contenu à partir du fichier incomplet. rar x --kb myincompletefile.rar . Pour 7zip voir même cette réponse . De quel type de serveur s'agit-il ? Utilisez-vous zip juste pour dire compressé ou vous vous référez strictement à zip des fichiers ?

0 votes

Je parle d'un fichier mis en ligne pour le téléchargement via le protocole http ou ftp ou même un torrent, et je me réfère strictement au fichier .zip.

0 votes

Alors j'ai bien peur que votre réponse soit いいえ . :-( Mais vous pouvez toujours commencer à télécharger, essayer de réparer/extraire la partie partielle, et voir s'il y a ce dont vous avez besoin.... Si vous vous référez à la distribution de logiciels avec un fichier zip unique sous ftp, parfois ils ont la "ouvert" version aussi que vous pouvez explorer comme un chemin normal ... Je pense à quelque chose comme CTAN des miroirs...

6voto

svz Points 131

J'ai écrit un Python script list_remote_zip.py qui peut lister les fichiers dans un fichier zip accessible par 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()

Il n'utilise pas le répertoire central du fichier zip, qui se trouve vers la fin du fichier. Au lieu de cela, il part du début, analyse les en-têtes locaux individuels et passe au-dessus de la charge utile, en espérant atterrir sur un autre en-tête. Il envoie une nouvelle requête chaque fois qu'il a besoin de passer à un décalage. Bien entendu, cela ne fonctionne qu'avec les serveurs qui prennent en charge la fonction Range En-tête HTTP.

Il suffit de lui transmettre l'URL du fichier zip comme argument de ligne de commande. Un exemple d'utilisation et de sortie devrait ressembler à ceci :

$ 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
...

Pour télécharger un des fichiers, j'ai écrit un fichier encore plus moche get_file_from_remote_zip.sh bash script autour de lui qui utilise 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"

Il faut 2 arguments. Le premier est l'URL du fichier zip et le second le fichier à extraire. Le nom du fichier à extraire doit être complet et exactement tel qu'il apparaît dans le résultat de l'opération précédente. list_remote_zip.py Python script, qu'il utilise pour obtenir des informations sur le fichier. Il utilise ensuite wget pour le télécharger avec le bon décalage et la bonne longueur. Il enregistre cette "tranche" de zip dans un fichier temporaire, qui est ensuite utilisé pour produire un fichier de type gzip -qui peut ensuite être acheminé et décompressé avec la commande gzip . La "tranche" elle-même n'est pas un fichier zip valide car elle n'a pas de répertoire central à la fin. Cela pourrait être corrigé avec zip 's -FF mais j'ai décidé de changer un peu les en-têtes et de le convertir en fichier gzip. Le (PK)zip et le gzip utilisent tous les deux le même fichier déflater L'algorithme de compression et même les sommes de contrôle CRC-32 semblent être compatibles.

Voici un exemple de la façon de télécharger un fichier aléatoire à partir de l'archive de Xonotic disponible à l'adresse suivante http://dl.xonotic.org/xonotic-0.8.1.zip , le décompresser et l'enregistrer dans un fichier local :

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

0 votes

Au fait, ce aidé.

0 votes

Le premier bloc de code est un script Python (2) que j'ai appelé list_remote_zip.py . Ainsi, si vous avez installé Python, vous pouvez le lancer et lui passer l'URL du fichier zip comme argument de ligne de commande, comme suit : python list_remote_zip.py http://dl.xonotic.org/xonotic-0.8.1.zip

3voto

rajiv Points 9

Montez le fichier ZIP distant via un système de fichiers virtuel soutenu par HTTP, puis utilisez la commande unzip standard sur celui-ci. De cette façon, les appels d'E/S de l'utilitaire unzip sont traduits en GETs de la gamme HTTP, ce qui signifie que seuls les morceaux du fichier ZIP que vous voulez sont transférés sur le réseau.

Voici un exemple pour Linux utilisant HTTPFS un système de fichiers virtuel très léger basé sur FUSE. Il existe des outils similaires pour Windows. Les langages de programmation comme Python et Java fournissent également des E/S HTTP, il suffit de les combiner de manière appropriée avec leur logique de lecture ZIP.

Obtenir/construire httpfs :

$ wget http://sourceforge.net/projects/httpfs/files/httpfs/1.06.07.02
$ tar -xjf httpfs_1.06.07.10.tar.bz2
$ rm httpfs
$ ./make_httpfs

Monter un fichier ZIP distant et en extraire un fichier :

$ mkdir mount_pt
$ sudo ./httpfs http://example.com/zipfile.zip mount_pt
$ ls mount_pt
zipfile.zip
$ unzip -p mount_pt/zipfile.zip the_file_I_want.txt > the_file_I_want.txt
$ sudo umount mount_pt

(besoin de sudo peut varier en fonction de la configuration de FUSE sur votre système).

Bien sûr, vous pouvez aussi utiliser d'autres outils que ceux de la ligne de commande.

1voto

Jack Points 599

Si vous accédez à un serveur de fichiers et que vous avez installé Winrar (et probablement d'autres applications similaires), vous pouvez ouvrir le fichier .zip et faire glisser les fichiers que vous voulez.

Si vous parlez d'un serveur web, je ne pense pas que vous puissiez le faire.

1voto

Loren Pechtel Points 2489

En supposant que le serveur prenne en charge la reprise des téléchargements, il serait en théorie possible d'écrire un client qui fasse cela - saisir un bloc suffisamment gros vers la fin pour obtenir le répertoire, puis l'utiliser pour déterminer ce que vous devez saisir pour obtenir réellement les données - commencer simplement à télécharger à cette position et arrêter quand vous avez assez de données. Cela fait tellement longtemps que je ne me souviens plus s'il y a un moyen de trouver le début du répertoire autrement que par la force brute.

Je n'ai jamais entendu parler d'un tel client et je ne peux pas imaginer pourquoi il serait développé - si ce sont des données qui seraient raisonnablement téléchargées en morceaux, alors pourquoi le webmaster les stocke dans un gros fichier zip ???

0 votes

Il y a des cas où vous téléchargez un gros fichier zip et certains fichiers sont corrompus, alors si cette solution existe, cela me facilitera la vie de ne télécharger que les fichiers corrompus.

0 votes

@habibhassani En d'autres termes, le fait qu'il s'agisse d'un fichier zip n'est pas vraiment pertinent, vous voulez juste récupérer un morceau endommagé d'un fichier.

0 votes

Exactement, cette question est basée sur mon expérience.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X