Как я могу преобразовать JarInputStream в JarFile без сохранения на диск? - PullRequest
2 голосов
/ 27 апреля 2011

У меня есть сервлет, на котором пользователь может загрузить файл .jar, чтобы проверить его MANIFEST.MF.

Я знаю, что будет работать следующее:

JarInputStream in = new JarInputStream(new ByteArrayInputStream (fileItem.get()));
Manifest mf = in.getManifest(); 

К сожалению, метод getManifest() анализирует для Key: Value и нуждается в ":" (двоеточие + пробел), простого двоеточия недостаточно. Поскольку мобильные телефоны, с которыми я работаю, также работают, если в MANIFEST.MF есть только двоеточия, а не двоеточие + пробел, я бы хотел извлечь MANIFEST.MF вручную, но я не хочу сохранять файл на диске.

Если бы у меня был JarFile, я мог бы проанализировать Манифест с помощью:

JarFile jarFile = new JarFile(fileName);
InputStream in = jarFile.getInputStream(jarFile.getEntry("META-INF/MANIFEST.MF"));
BufferedReader br = new BufferedReader(new InputStreamReader(in));

String line;
while ((line = br.readLine()) != null) {
    String[] splitAr = line.split(":", 0);
    // ...

Но, к сожалению, я понятия не имею, как я мог бы преобразовать JarInputStream (или ByteArrayInputStream) в JarFile.

Ответы [ 4 ]

4 голосов
/ 27 апреля 2011

Что бы я попытался сделать в этом случае:

  • переберите все записи в банке, используя getNextEntry() - не getNextJarEntry()! и посмотрим, сможете ли вы достичь манифеста таким образом
  • попробуйте использовать ZipInputStream вместо этого, который является более общим - JarInputStream фактически расширяет его - и это должно дать вам доступ к файлу META-INF/MANIFEST.MF.
2 голосов
/ 27 апреля 2011

Это не поддерживается стандартным API. Единственный способ создать JarFile - предоставить ссылку File, и, поскольку API не предоставляет интерфейс для создания «специальных файлов», поддерживаемых, например, InputStream, его невозможно решить.

Если вы работаете в системе UNIX, вы, вероятно, могли бы настроить файл устройства как-нибудь, но вы потеряли бы переносимость.

0 голосов
/ 08 ноября 2013

Вы можете прочитать манифест из входного потока в виде строки и проанализировать его самостоятельно

/**
 * Read JAR  manifest as String from input stream.
 * Like JarInputStream, assume that META-INF/MANIFEST.MF entry  should be either 
 * the first or the second entry (when preceded  by the dir META-INF/).
 */
def readManifestAsString(InputStream is) {
    def zip = new ZipInputStream(is);
    def e = zip.getNextEntry();
    if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
        e =  zip.getNextEntry();  
    if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
        byte[] bytes = getBytes(new BufferedInputStream(zip));
        return new String(bytes, "UTF8");
     }
}

byte[] getBytes(InputStream is) {
        byte[] buffer = new byte[8192];
        ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
        int n;
        while ((n = is.read(buffer, 0, buffer.length)) != -1) {
            baos.write(buffer, 0, n);
        }
        return baos.toByteArray();
 }

Спецификация JAR-манифеста может быть найдена здесь

0 голосов
/ 21 июня 2012
  private static void copyFiles(JarInputStream in, JarOutputStream out)
    throws IOException
  {
    JarEntry inEntry;
    byte[] buffer = new byte[4096];

    while ((inEntry=(JarEntry)in.getNextEntry())!=null)
          {if (inEntry.getMethod()==0)
              {out.putNextEntry(new JarEntry(inEntry));
              }
           else
               {out.putNextEntry(new JarEntry(inEntry.getName()));
               }
           //InputStream data=in;//the call to ZipInputStream.getNextEntry() positions the InputStream at the start of the entry and therefore supplying the ZipInputStream is the equivalent of supplying a ZipEntry's InputStream.the ZipInputStream is smart enough to handle the entry's EOF downstream
           int num;
           while ((len=/*data*/in.read(buffer))>0)
                 {out.write(buffer, 0, len);
                 }
           out.flush();
          }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...