Как обрабатывать длинные имена файлов GNU в Java при использовании классов org.apache.tools.tar.*, упакованных с помощью install4j?

Я пытаюсь добавить сценарий запуска в install4j, который обрабатывает распаковку и распаковку архивов для таких вещей, как mysql и tomcat, которые встраиваются в мой установщик. Я понимаю, что могу взорвать эти файлы tar как часть процесса сборки в ant, но по крайней мере для одного варианта использования я не могу этого сделать.

Я включил приведенный ниже код в действие «Выполнить сценарий», используя классы org.apache.tools.tar.TarEntry и TarInputStream. Это работает достаточно хорошо, с одной ошибкой.

При использовании этой реализации пути к файлам, длина которых превышает 99 символов, усекаются, а результирующие файлы переносятся в каталог верхнего уровня.

Я пытаюсь выяснить, является ли это ошибкой в ​​​​моей реализации или проблемой с классами инструментов apache. Кажется, tarEntry.getName() не возвращает весь путь, если он превышает 99 символов. Есть ли простой способ обойти это без необходимости переписывать то, что делает TarInputStream? В Tar.Entry есть метод isGNULongNameEntry, но я не могу найти надежный способ указать, куда поместить файл, когда он возвращает значение true.

Какие-либо предложения?

import java.io.*;
import java.util.zip.*;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

String outputDirectory = "mysql";
File tgzFile = new File(context.getInstallationDirectory(), outputDirectory + File.separator + "mysql-5.5.17-linux2.6-i686.tar.gz");

// Create the Tar input stream.
FileInputStream fin = new FileInputStream(tgzFile);
GZIPInputStream gin = new GZIPInputStream(fin);
TarInputStream tin = new TarInputStream(gin);

// Create the destination directory.
File outputDir = new File(outputDirectory);
outputDir.mkdir();

// Extract files.
TarEntry tarEntry = tin.getNextEntry();
while (tarEntry != null) {
    File destPath = new File(context.getInstallationDirectory(), outputDirectory + File.separator + tarEntry.getName());

tarEntry.isGNULongNameEntry()

    if (tarEntry.isDirectory()) {
        destPath.mkdirs();
    } else {
        // If the parent directory of a file doesn't exist, create it.
        if (!destPath.getParentFile().exists())
            destPath.getParentFile().mkdirs();

        FileOutputStream fout = new FileOutputStream(destPath);
        tin.copyEntryContents(fout);
        fout.close();
    // Presserve the last modified date of the tar'd files.
        destPath.setLastModified(tarEntry.getModTime().getTime());
    }
    tarEntry = tin.getNextEntry();
}
tin.close();

return true;

person Frank    schedule 09.02.2012    source источник


Ответы (2)


Не стесняйтесь взглянуть на предложенный мной патч для этой проблемы с распаковкой. дать вам несколько указателей по крайней мере.

person Peter Svensson    schedule 09.02.2012
comment
Спасибо, Питер, по крайней мере, это помогает мне знать, что я не единственный, кто занимается подобными проблемами. Ничего себе, вы представили это довольно давно. Я удивлен, что они не подобрали патч. - person Frank; 09.02.2012

Хотя длинные имена файлов в tar-файлах POSIX не обрабатываются tar-библиотекой apache, вы можете использовать GNU tar для создания tar-файлов. В этом случае не будет проблем с длинными именами файлов.

person Ingo Kegel    schedule 10.02.2012
comment
Да, проблема в том, что я не контролирую tar-файлы, с которыми имею дело, они распространяются третьими лицами. Я мог бы распаковать и перезапустить их, но это не лучший обходной путь. - person Frank; 10.02.2012