给定:
- 归档文件的URL(例如zip文件)
- 归档文件内的完整文件名(包括路径)
我正在寻找一种方法(最好使用Java),可以创建该文件的本地副本,而无需先下载整个归档文件。
据我(有限)的了解,这应该是可能的,但我不知道如何做到。我一直在使用TrueZip,因为它似乎支持多种归档类型,但我对其以这种方式工作的能力表示怀疑。有人有类似的经验吗?
编辑:我也希望能够使用tarballs和zipped 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);
当然,这还没有经过测试。
Range
HTTP头才能实现此功能。de.schlichtherle.io.rof.ReadOnlyFile
并创建一个de.schlichtherle.util.zip.ZipFile
。从 TrueZIP 7.2 版本开始,模块 TrueZIP Path 中提供了新的客户端 API。该 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,该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);
}
}