Если по Открытому исходному коду, Вы действительно имели в виду "свободный", то Microsoft предбыстрый анализ является хорошей. Только для Windows, конечно. Это полностью интегрируется в Visual Studio & компилятор. например:
cl /analyze Sample.cpp
На самом деле это состоит из двух частей :)
Во-первых, что бы люди ни говорили, zip-файлы не могут технически дословно помещаться в конец файлов. Конец записи центрального каталога имеет значение, которое указывает байтовое смещение от начала текущего диска (если у вас только один файл .zip, это означает текущий файл). Сейчас многие процессоры игнорируют это, хотя zip-папка Windows этого не делает, поэтому вам нужно исправить это значение, чтобы она работала в проводнике Windows (не то, чтобы вас это волновало; P) См. Zip APPNOTE для получения информации о формат файла. Обычно вы находите в шестнадцатеричном редакторе (или пишете инструмент) значение «смещения начала центрального каталога относительно начального номера диска». Затем найдите первую "подпись заголовка центрального файла" (шестнадцатеричное значение 504b0102) и установите значение для этого смещения.
Увы, это не исправляет 7zip, но это связано с тем, как 7zip пытается угадать формат файла. По сути, он будет искать только первые ~ 4 МБ для двоичной последовательности 504b0304, если не найдет, он предполагает, что это не Zip, и пробует другие форматы архива. Очевидно, поэтому добавление еще одного файла ломает вещи, это увеличивает предел поиска.
Теперь, чтобы исправить это, вам нужно добавить эту шестнадцатеричную строку в jpeg, не нарушая ее. Один из способов сделать это - добавить сразу после заголовка FFD8 JPEG SOI следующие шестнадцатеричные данные, FFEF0005504B030400. Это добавляет настраиваемый блок с вашей последовательностью и является правильным, поэтому заголовки jpeg должны просто игнорировать его.
t исправить 7zip, но это связано с тем, что 7zip пытается угадать формат файла. По сути, он будет искать только первые ~ 4 МБ для двоичной последовательности 504b0304, если не найдет, он предполагает, что это не Zip, и пробует другие форматы архива. Очевидно, поэтому добавление еще одного файла ломает вещи, это увеличивает предел поиска.Теперь, чтобы исправить это, вам нужно добавить эту шестнадцатеричную строку в jpeg, не нарушая ее. Один из способов сделать это - добавить сразу после заголовка FFD8 JPEG SOI следующие шестнадцатеричные данные, FFEF0005504B030400. Это добавляет настраиваемый блок с вашей последовательностью и является правильным, поэтому заголовки jpeg должны просто игнорировать его.
t исправить 7zip, но это связано с тем, что 7zip пытается угадать формат файла. По сути, он будет искать только первые ~ 4 МБ для двоичной последовательности 504b0304, если не найдет, он предполагает, что это не Zip, и пробует другие форматы архива. Очевидно, поэтому добавление еще одного файла ломает вещи, оно увеличивает предел поиска.Теперь, чтобы исправить это, вам нужно добавить эту шестнадцатеричную строку в jpeg, не нарушая ее. Один из способов сделать это - добавить сразу после заголовка FFD8 JPEG SOI следующие шестнадцатеричные данные, FFEF0005504B030400. Это добавляет настраиваемый блок с вашей последовательностью и является правильным, поэтому заголовки jpeg должны просто игнорировать его.
Очевидно, поэтому добавление еще одного файла ломает вещи, оно увеличивает предел поиска.Теперь, чтобы исправить это, вам нужно добавить эту шестнадцатеричную строку в jpeg, не нарушая ее. Один из способов сделать это - добавить сразу после заголовка FFD8 JPEG SOI следующие шестнадцатеричные данные, FFEF0005504B030400. Это добавляет настраиваемый блок с вашей последовательностью и является правильным, поэтому заголовки jpeg должны просто игнорировать его.
Очевидно, поэтому добавление еще одного файла ломает вещи, оно увеличивает предел поиска.Теперь, чтобы исправить это, вам нужно добавить эту шестнадцатеричную строку в jpeg, не нарушая ее. Один из способов сделать это - добавить сразу после заголовка FFD8 JPEG SOI следующие шестнадцатеричные данные, FFEF0005504B030400. Это добавляет настраиваемый блок с вашей последовательностью и является правильным, поэтому заголовки jpeg должны просто игнорировать его.
Я загрузил исходный код для 7-Zip и выяснил, что является причиной этого.
В CPP / 7zip / UI / Common / OpenArchive.cpp вы увидите следующее :
// Static-SFX (for Linux) can be big.
const UInt64 kMaxCheckStartPosition = 1 << 22;
Это означает, что поиск заголовка будет выполняться только в первых 4194304 байтах файла. Если его там нет, 7-Zip считает его недопустимым файлом.
Вы можете удвоить это ограничение, изменив 1 << 22
на 1 << 23
. Я протестировал это изменение, перестроив 7-Zip, и оно работает.
РЕДАКТИРОВАТЬ : Чтобы обойти эту проблему, вы можете загрузить исходный код , внести вышеуказанное изменение и собрать его. Я построил его с помощью VS 2008. Откройте командную строку VS, перейдите в местоположение-извлеченного-источника \ CPP \ 7zip \ Bundles и введите «nmake». Затем в каталоге Alone запустите "7za t nonworking.jpg".
Итак, для всех, кто задает этот вопрос, вот история:
Да, Энди буквально прав в том, почему 7-Zip не работает с файлом, но это не помогает моему проблема, поскольку я не могу убедить людей использовать МОЮ версию 7-Zip.
тиранид, однако, дал мне решение.
#Now we need to read the file and rewrite all the zip headers. Fun!
torewrite = open(magicfilename, 'rb')
magicdata = torewrite.read()
torewrite.close()
#Change the Central Repository's Offset
offsetOfCentralRepro = magicdata.find('\x50\x4B\x01\x02') #this is the beginning of the central repo
start = len(magicdata) - 6 #it so happens, that on my files, the point is stored 2 bytes from the end. so datadatadatdaata OF FS ET !! 00 00 EOF where OFFSET!! is the 4 bytes 00 00 are the last two bytes, then EOF
magicdata = magicdata[:start] + pack('I', offsetOfCentralRepro) + magicdata[start+4:]
#Now change the individual offsets in the central directory files
startOfCentralDirectoryEntry = magicdata.find('\x50\x4B\x01\x02', 0) #find the first central directory entry
startOfFileDirectoryEntry = magicdata.find('\x50\x4B\x03\x04', 10) #find the first file entry (we start at 10 because we have to skip past the first fake entry in the jpg)
while startOfCentralDirectoryEntry > 0:
#Now I move a magic number of bytes past the entry (really! It's 42!)
startOfCentralDirectoryEntry = startOfCentralDirectoryEntry + 42
#get the current offset just to output something to the terminal
(oldoffset,) = unpack('I', magicdata[startOfCentralDirectoryEntry : startOfCentralDirectoryEntry+4])
print "Old Offset: ", oldoffset, " New Offset: ", startOfFileDirectoryEntry , " at ", startOfCentralDirectoryEntry
#now replace it
magicdata = magicdata[:startOfCentralDirectoryEntry] + pack('I', startOfFileDirectoryEntry) + magicdata[startOfCentralDirectoryEntry+4:]
#now I move to the next central directory entry, and the next file entry
startOfCentralDirectoryEntry = magicdata.find('\x50\x4B\x01\x02', startOfCentralDirectoryEntry)
startOfFileDirectoryEntry = magicdata.find('\x50\x4B\x03\x04', startOfFileDirectoryEntry+1)
#Finally write the rewritten headers' data
towrite = open(magicfilename, 'wb')
towrite.write(magicdata)
towrite.close()
Вы можете создавать гибридные файлы JPG + ZIP, используя DotNetZip . DotNetZip может сохранять в поток, и он достаточно умен, чтобы распознать исходное смещение уже существующего потока, прежде чем он начнет записывать в него zip-содержимое. Следовательно, в псевдокоде вы можете получить JPG + ZIP следующим образом:
open stream on an existing JPG file for update
seek to the end of that stream
open or create a zip file
call ZipFile.Save to write zip content to the JPG stream
close
Все смещения рассчитаны правильно. Тот же метод используется для создания самораспаковывающегося архива. Вы можете открыть поток в EXE, затем перейти к концу и записать содержимое ZIP в этот поток. Если вы сделаете это таким образом, все смещения будут рассчитаны правильно.
Другое дело - по поводу одного из комментариев в другом посте ... ZIP может иметь произвольные данные в начале и в конце файла. Насколько я знаю, не требуется, чтобы центральный каталог zip располагался в конце файла, хотя это типично.