Как интерпретатор Python определяет, что он был вызван с ZIP-архивом, а не с исходным файлом?

Я только что узнал, что (A) ZIP-файл может быть передан непосредственно как параметр script (где обычно передается файл .py) двоичного файла Python и (B) ZIP-файл может иметь любой суффикс, даже .py, чтобы его распознали. в виде ZIP-файла (по крайней мере, в Mac OS X из командной строки и в Windows из командной строки и из графического интерфейса, похоже, это работает). Вся история реализации описана в этой проблеме.

Это кажется очень привлекательным для распространения приложений Python, где установщик нежелателен, и он имеет те же характеристики использования, что и .jar архив (не требует установки, может быть отправлен по электронной почте без дальнейшего архивирования), к которым привыкли наши пользователи. Присвоение ZIP-архиву имени .py (или .pyw) обеспечивает такое поведение без какой-либо настройки на клиентском компьютере, кроме установки Python.

Моя проблема в том, что я могу найти документацию только для части (A) моих выводов, но не для части (B). Итак, мой первый вопрос: как Python определяет, что файл, переданный в качестве параметра script, является ZIP-архивом, а не исходным файлом Python? Существуют ли какие-либо эвристики, которые могут случайно сломаться, например. когда ZIP-архив содержит какой-то особый контент (например, несжатый файл, который выглядит как код Python)?

Второй вопрос заключается в том, есть ли какие-то недостатки у такого подхода, когда приложение носит с собой много файлов данных, не являющихся кодом (десятки мегабайт), помимо того, что доступ к этим файлам непрозрачен. Я думаю, что обнаружение ZIP-файла занимает больше времени, если ZIP-файл большой и/или содержит много файлов.

Обновить

Все ответы до сих пор (Иоахима Зауэра, Кита Рэндалла и Любопытного), к сожалению, неверны. Спецификация Zip не требует, чтобы ZIP-файл начинался с определенного заголовка. Zip-файл может иметь любые данные, добавленные к нему, и по-прежнему быть действительным Zip-файлом (именно так работают самораспаковывающиеся Zip-файлы, когда файл начинается с заголовка Windows EXE, а не с чего-либо, специфичного для Zip). Это объясняется на странице, связанной с ответом Curious.

Я предполагаю, что интерпретатор Python ищет центральный каталог Zip, и если он есть, файл используется как Zip-файл вместо исходного файла Python. Кто-нибудь хочет включить это в свой ответ, чтобы я мог его принять?


person Feuermurmel    schedule 29.08.2012    source источник


Ответы (2)


Все файлы ZIP (и все производные форматы, такие как файлы .jar) начинаются с символов ASCII. "PK" (и еще два байта, которые не составляют значимых символов ASCII).

Они называются магическими числами и являются распространенным способом определения типа файла при его отсутствии. внешней информации (расширение файла или MIME-тип).

Поскольку необходимо прочитать только самые первые байты, определение того, является ли файл ZIP-файлом, выполняется одинаково быстро, независимо от размера архива. Определить, является ли ZIP-файл правильным и неповрежденным, — это другое дело, но обычно это не делается, если это явно не запрошено.

person Joachim Sauer    schedule 29.08.2012

Zip-файлы обычно распознаются не по расширению файла, а по магическому номеру в конце файла. начало файла. Первые 4 байта всегда равны 0x50 0x4b 0x03 0x04.

person Keith Randall    schedule 29.08.2012