Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получение содержимого архива, Получение содержимого архива 
:(
    Опции темы
Amp
Дата 1.7.2010, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: 3
Всего: 17



Цитата(LSD @  1.7.2010,  15:52 Найти цитируемый пост)
В ZIP директории отличаются от файлов тем, что у них нет содержимого в виде данных, в остальном они эквивалентны.

Но я говорил о другом, что даже если искомый элемент находится в конце файла нам не нужно выделять память (ни дисковую ни оперативную) на распаковку всего архива. 

Skipy писал скорее всего о central directory - структуре, расположенной в конце zip-файла, содержащей смещения на уже отдельные entry со сжатыми данными у каждого файла из архива. И чтобы получить список файлов необходимо прочитать все заголовки, которые содержит в себе cental directory. А чтобы прочитать central directory у запакованного в zip zip же архива - этот архив придется куда-нибудь распаковать (на диск там или в память), и только затем производить в нем позиционировании и считывание.
PM MAIL   Вверх
Skipy
Дата 2.7.2010, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

Репутация: 6
Всего: 16



Именно об этом. Если мы читаем zip-файл из zip-файла, то чтобы вычитать содержимое внутреннего файла, даже структуру - надо спозиционироваться на директорию. А она лежит в конце файла. И чтобы вычислить точку, где она начинается (смещение известно) - надо распаковать весь внутренный файл и спозиционироваться в нем по этому смещению. Так что хочешь-не хочешь, а внутренний файл придется все-таки распаковать целиком.

Это сообщение отредактировал(а) Skipy - 2.7.2010, 09:11


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
LSD
Дата 6.7.2010, 12:18 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Skipy @  2.7.2010,  10:10 Найти цитируемый пост)
Если мы читаем zip-файл из zip-файла, то чтобы вычитать содержимое внутреннего файла, даже структуру - надо спозиционироваться на директорию. А она лежит в конце файла. И чтобы вычислить точку, где она начинается (смещение известно) - надо распаковать весь внутренный файл и спозиционироваться в нем по этому смещению. Так что хочешь-не хочешь, а внутренний файл придется все-таки распаковать целиком.

Это в теории. На практике же, если файл содержит только entries и central directory без лишних данных, вполне можно обойтись и без предварительного чтения central directory, можно просто сканировать поток на предмет entries и при желании сразу же их распаковывать.

Код

package vingrad;

import org.apache.log4j.Logger;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipStreamTest
{
  private static final Logger logger = Logger.getLogger(ZipStreamTest.class);

  public static void main(String[] args)
  {
    try
    {
      Logger earLogger = Logger.getLogger("ear");
      InputStream ear = new LoggingInputStream(earLogger, new FileInputStream("C:\\TEMP\\EntAPI.ear"));
      ZipInputStream earZipInputStream = new ZipInputStream(ear);
      ZipEntry earEntry;
      while((earEntry = earZipInputStream.getNextEntry()) != null)
      {
        String name = earEntry.getName();
        if(name.toLowerCase().endsWith(".war"))
        {
          Logger warLogger = Logger.getLogger("war");
          InputStream war = new LoggingInputStream(warLogger, earZipInputStream);
          ZipInputStream warZipInputStream = new ZipInputStream(war);
          ZipEntry warEntry;
          while((warEntry = warZipInputStream.getNextEntry()) != null)
          {
            warLogger.info("  WAR: " + warEntry.getName());
          }
        }
      }
      ear.close();
    }
    catch(Exception e)
    {
      logger.error(e, e);
    }
  }

  public static class LoggingInputStream extends InputStream
  {
    public static final int DEFAUL_BLOCK_SIZE = 1024;

    private InputStream out;
    private int blockSize;
    private int written = 0;
    private final Logger logger;

    public LoggingInputStream(Logger logger, InputStream in, int blockSize)
    {
      this.out = in;
      this.blockSize = blockSize;
      this.logger = logger;
      logger.info("Start reading");
    }


    public LoggingInputStream(Logger logger, InputStream in)
    {
      this(logger, in, DEFAUL_BLOCK_SIZE);
    }


    private void increment(int amount)
    {
      int prevBlocks = written / blockSize;
      written += amount;
      int currentBlocks = written / blockSize;
      if(prevBlocks < currentBlocks && logger.isInfoEnabled())
      {
        logger.info(String.format("Read %,10d bytes", written));
      }
    }

    public int read() throws IOException
    {
      int b = out.read();
      increment(1);
      return b;
    }

    public int read(byte[] b) throws IOException
    {
      int read = out.read(b);
      increment(read);
      return read;
    }

    public int read(byte[] b, int off, int len) throws IOException
    {
      int read = out.read(b, off, len);
      increment(read);
      return read;
    }

    public long skip(long n) throws IOException
    {
      long skipped = out.skip(n);
      increment((int) skipped);
      return skipped;
    }

    public int available() throws IOException
    {
      return out.available();
    }

    public void close() throws IOException
    {
      out.close();
      logger.info("Stop reading");
    }

    public void mark(int readlimit)
    {
    }

    public void reset() throws IOException
    {
    }

    public boolean markSupported()
    {
      return false;
    }
  }
}

и по логам прекрасно видно, что последовательно читаются EAR файл, из него на лету извлекается WAR и читается его содержимое, без необходимости распаковывать до конца и читать central directory
Код

[INFO ] [ear] Start reading
[INFO ] [war] Start reading
[INFO ] [ear] Read      1 125 bytes
[INFO ] [war]   WAR: META-INF/
[INFO ] [war]   WAR: META-INF/MANIFEST.MF
[INFO ] [war]   WAR: WEB-INF/
[INFO ] [war]   WAR: WEB-INF/classes/
[INFO ] [war]   WAR: WEB-INF/classes/config/
[INFO ] [war]   WAR: WEB-INF/classes/config/SWSServiceLibrary/
[INFO ] [war]   WAR: WEB-INF/lib/
[INFO ] [war]   WAR: sws_services/
[INFO ] [war]   WAR: WEB-INF/weblogic.xml
[INFO ] [war] Read      1 218 bytes
[INFO ] [war]   WAR: WEB-INF/web.xml
[INFO ] [ear] Read      2 149 bytes
[INFO ] [war] Read      2 264 bytes
[INFO ] [war]   WAR: WEB-INF/classes/config/SWSServiceLibrary/SWS_Service.properties
[INFO ] [war]   WAR: WEB-INF/classes/config/SWSServiceLibrary/ServiceRegistryListResponse.xsd
[INFO ] [ear] Read      3 173 bytes
[INFO ] [war]   WAR: WEB-INF/classes/config/SWSServiceLibrary/SWSInit.properties
[INFO ] [war]   WAR: WEB-INF/classes/config/SWSServiceLibrary/SWSServiceRequest.xsd
[INFO ] [war] Read      3 122 bytes
[INFO ] [war]   WAR: WEB-INF/classes/config/SWSServiceLibrary/SWSServiceResponse.xsd
[INFO ] [war]   WAR: WEB-INF/classes/config/SWSFramework.properties
[INFO ] [ear] Read      4 197 bytes
[INFO ] [war] Read      4 168 bytes
[INFO ] [war]   WAR: WEB-INF/lib/gpfs-entitlement-impl-1.3.1.jar
[INFO ] [ear] Read      5 221 bytes
[INFO ] [war] Read      5 241 bytes
[INFO ] [ear] Read      6 245 bytes
[INFO ] [war] Read      6 264 bytes
[INFO ] [ear] Read      7 269 bytes
[INFO ] [war] Read      7 287 bytes
[INFO ] [ear] Read      8 293 bytes
[INFO ] [war] Read      8 309 bytes
[INFO ] [ear] Read      9 317 bytes
[INFO ] [war] Read      9 333 bytes
[INFO ] [ear] Read     10 341 bytes
[INFO ] [war] Read     10 356 bytes
[INFO ] [ear] Read     11 365 bytes
[INFO ] [war] Read     11 379 bytes
[INFO ] [ear] Read     12 389 bytes
[INFO ] [war] Read     12 404 bytes
[INFO ] [ear] Read     13 413 bytes
[INFO ] [war] Read     13 427 bytes
[INFO ] [ear] Read     14 437 bytes
<......>



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0573 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.