鑑於歸檔的如何從遠程存檔文件中提取單個文件?
- 網址存檔中的文件(如zip文件)
- 全名(包括路徑)
我正在尋找一種方式(最好是在Java)創建該文件的本地副本,,而無需首先下載整個存檔。
從我(有限)的理解,它應該是可能的,但我不知道該怎麼做。我一直在使用TrueZip,因爲它似乎支持大量的存檔類型,但我對它以這種方式工作的能力感到懷疑。有沒有人有這種事情的經驗?
編輯:也可以做到這一點與tarballs和壓縮tarballs對我也很重要。
鑑於歸檔的如何從遠程存檔文件中提取單個文件?
我正在尋找一種方式(最好是在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 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);
}
}
不幸的是,我不是託管這些文件的人......但這是一個很好的觀點。 – Oak 2010-06-28 07:34:46
相反,其他的答案,我會喜歡指出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檔案。 – Oak 2010-06-27 07:21:45
嗯,你爲什麼認爲它叫做'ZipInputStream'? ;-)如果你環顧網絡,你可能會找到一個'TarInputStream',你可以使用大致相同的方式 - 或者,如果不是,你可以編寫自己的。這很容易,因爲tar文件沒有壓縮,它基本上只是每個文件的頭文件,後面是文件數據。 (維基百科對格式有描述)對於gzip tar檔案,Java的標準庫有一個'GZIPInputStream',你可以使用tar流。 – 2010-06-27 19:59:56
確實,Apache有一個[TarInputStream](http://javadoc.haefelinger.it/org.apache.ant/1.7.1/org/apache/tools/tar/TarInputStream.html)類:) – Oak 2010-06-28 07:42:16