Данный
Я ищу путь (предпочтительно в Java) для создания локальной копии того файла, не загружая весь архив сначала.
От моего (ограниченного) понимания это должно быть возможно, хотя я понятия не имею, как сделать это. Я использовал TrueZip, так как это, кажется, поддерживает большое множество типов архивирования, но у меня есть сомнения относительно его способности работать таким способом. У кого-либо есть опыт с такой вещью?
Править: способность также сделать это с tarballs и архивировало tarballs, также важно для меня.
Ну, как минимум, вы должны загрузить часть архива, включая сжатые данные файла, который вы хотите извлечь. Это предлагает следующее решение: открыть URLConnection
к архиву, получить его входной поток, заключить его в ZipInputStream
и несколько раз вызвать getNextEntry ()
и closeEntry ()
, чтобы перебрать все записи в файле, пока не дойдете до нужной. Затем вы можете прочитать его данные, используя ZipInputStream.read (...)
.
Код Java мог бы выглядеть примерно так:
URL url = new URL("http://example.com/path/to/archive");
ZipInputStream zin = new ZipInputStream(url.getInputStream());
ZipEntry ze = zin.getNextEntry();
while (!ze.getName().equals(pathToFile)) {
zin.closeEntry(); // not sure whether this is necessary
ze = zin.getNextEntry();
}
byte[] bytes = new byte[ze.getSize()];
zin.read(bytes);
Это, конечно, не проверено.
Я не уверен, есть ли способ вытащить извлекать один файл из ZIP-архива, не скачивая его целиком. Но если вы размещаете ZIP-файл, вы можете создать Java-сервлет, который читает ZIP-файл и возвращает запрошенный файл в ответе:
public class GetFileFromZIPServlet extends HttpServlet{
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
String pathToFile = request.getParameter("pathToFile");
byte fileBytes[];
//get the bytes of the file from the ZIP
//set the appropriate content type, maybe based on the file extension
response.setContentType("...");
//write file to the response
response.getOutputStream().write(fileBytes);
}
}
В отличие от других ответов здесь, я хотел бы отметить, что записи ZIP сжимаются по отдельности, поэтому (теоретически) вам не нужно загружать ничего, кроме каталога и самой записи. Чтобы это работало, сервер должен поддерживать HTTP-заголовок Range
.
Стандартный Java API поддерживает только чтение ZIP-файлов из локальных файлов и входных потоков. Насколько я знаю, не предусмотрено чтение из удаленных файлов с произвольным доступом.
Поскольку вы используете TrueZip, я рекомендую реализовать de.schlichtherle.io.rof.ReadOnlyFile
с помощью Apache HTTP Client и создать de.schlichtherle.util.zip.ZipFile
с его помощью.
Это не даст никаких преимуществ для сжатых TAR-архивов, поскольку весь архив сжимается вместе (помимо использования InputStream и его уничтожения после записи).