如何从远程存档文件中提取单个文件?

特定

  1. 存档的URL(例如zip文件)
  2. 该存档内文件的全名(包括路径)

我正在寻找一种方法(最好是在Java中)来创建该文件的本地副本, 而无需先下载整个存档

从我(有限的)理解应该是可能的,虽然我不知道如何做到这一点。 我一直在使用TrueZip ,因为它似乎支持各种各样的存档类型,但我对它以这种方式工作的能力存有疑虑。 有没有人有这种经历?

编辑:能够用tarball和压缩的tarball做到这一点对我来说也很重要。

好吧,至少,您必须下载存档的部分,包括要提取的文件的压缩数据。 这表明以下解决方案:打开URLConnection到存档,获取其输入流,将其包装在ZipInputStream ,并重复调用closeEntry()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条目是单独压缩的,因此(理论上)您不需要下载除目录和条目本身之外的任何内容。 服务器需要支持Range HTTP标头才能工作。

标准Java API仅支持从本地文件和输入流中读取ZIP文件。 据我所知,没有从随机访问远程文件中读取的规定。

由于您使用的是TrueZip,我建议使用Apache HTTP Client实现de.schlichtherle.io.rof.ReadOnlyFile使用它创建de.schlichtherle.util.zip.ZipFile

这不会为压缩的TAR存档提供任何优势,因为整个存档被压缩在一起(除了使用InputStream并在您输入时将其终止)。

从TrueZIP 7.2开始,模块TrueZIP Path中有一个新的客户端API。 这是JSE 7的NIO.2 FileSystemProvider的实现。使用此API,您可以按如下方式访问HTTP URI:

 Path path = new TPath(new URI("http://acme.com/download/everything.tar.gz/README.TXT")); try (InputStream in = Files.newInputStream(path)) { // Read archive entry contents here. ... } 

我不确定是否有办法从ZIP中提取单个文件而不先下载整个文件。 但是,如果你是托管ZIP文件的那个,你可以创建一个Java servlet来读取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); } }