Java - удаление META-INF из банки не работает
В настоящее время я работаю над приложением, которое устанавливает моды в Minecraft, и я почти закончил версию 3.1DEV, единственное, что меня останавливает, это то, что мой код просто не удалит META-INF, вот мой код
ZipInputStream modZip = new ZipInputStream(new FileInputStream(mod.getDir()));
ZipInputStream minecraftZip = new ZipInputStream(new FileInputStream(new File(mcDir + "\\bin\\", "minecraft.jar")));
ZipOutputStream tmpZip = new ZipOutputStream(new FileOutputStream(new File("temp\\tmp.jar")));
byte[] buffer = new byte[1024];
for(ZipEntry ze = modZip.getNextEntry(); ze != null; ze = modZip.getNextEntry())
{
tmpZip.putNextEntry(ze);
for(int read = modZip.read(buffer); read != -1; read = modZip.read(buffer))
{
tmpZip.write(buffer, 0, read);
}
tmpZip.closeEntry();
}
modZip.close();
for(ZipEntry ze = minecraftZip.getNextEntry(); ze != null; ze = minecraftZip.getNextEntry())
{
try
{
boolean isMetaInf = false;
if(ze.getName().contains("META-INF"))
{
isMetaInf = true;
}
if(!isMetaInf)
{
tmpZip.putNextEntry(ze);
for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer))
{
tmpZip.write(buffer, 0, read);
}
tmpZip.closeEntry();
}
}
catch(Exception e)
{
continue;
}
}
minecraftZip.close();
tmpZip.flush();
tmpZip.close();
File tmp = new File("temp//tmp.jar");
tmp.renameTo(new File("temp//minecraft.jar"));
File minecraft = new File(mcDir + "\\bin\\minecraft.jar");
minecraft.delete();
FileUtils.copyFile(new File("temp\\minecraft.jar"), minecraft);
tmp.delete();
Любые ссылки или примеры приветствуются
- Лиам, генеральный директор Hachi Software
1 ответ
Проблема с логикой, давайте пройдемся по ней:
- Когда вы в первый раз найдете папку META-INF, вы установите для флага значение true. Ничего другого в цикле не может произойти, поэтому мы продолжаем
- На следующей итерации цикла вы сбрасываете флаг на false и переходите в
!isMetaInf
раздел Запись zip добавляется к временному zip:
tmpZip.putNextEntry(ze);
Вы пишете весь zip-файл для майнкрафта, от начала и до конца, во временный почтовый индекс:
for(int read = minecraftZip.read(buffer); read != -1; read = minecraftZip.read(buffer)) { tmpZip.write(buffer, 0, read); } tmpZip.closeEntry();
На этом этапе вы не выходите из цикла, поэтому этот процесс повторяется для каждого файла в банке.
Если вы просто удалите ручной цикл чтения и записи, вы можете позволить ZipOutputStream делать всю запись за вас, когда вы вызываете close()
в конце, или если вы используете Java 7, вы можете сделать этот код очень простым с помощью try-with-resources:
public static void copyWithoutMetaInf(final String originalZip, final String newZip) throws IOException
{
try (final ZipInputStream zip = new ZipInputStream(new FileInputStream(originalZip));
final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(newZip)))
{
ZipEntry entry;
while((entry = zip.getNextEntry()) != null)
{
if(!entry.getName().contains("META-INF"))
{
zop.putNextEntry(entry);
}
}
}
}
public static void main(String[] args) throws IOException
{
copyWithoutMetaInf("1.6.4.jar", "copy.jar");
}
Или без, для более старых версий:
public static void copyWithoutMetaInf(final String originalZip, final String newZip) throws IOException
{
final ZipInputStream zip = new ZipInputStream(new FileInputStream(originalZip));
final ZipOutputStream zop = new ZipOutputStream(new FileOutputStream(newZip));
ZipEntry entry;
while((entry = zip.getNextEntry()) != null)
{
if(!entry.getName().contains("META-INF"))
{
zop.putNextEntry(entry);
}
}
zip.close();
zop.close();
}