2010-06-26 44 views
10

鑑於歸檔的如何從遠程存檔文件中提取單個文件?

  1. 網址存檔中的文件(如zip文件)
  2. 全名(包括路徑)

我正在尋找一種方式(最好是在Java)創建該文件的本地副本,,而無需首先下載整個存檔

從我(有限)的理解,它應該是可能的,但我不知道該怎麼做。我一直在使用TrueZip,因爲它似乎支持大量的存檔類型,但我對它以這種方式工作的能力感到懷疑。有沒有人有這種事情的經驗?

編輯:也可以做到這一點與tarballs和壓縮tarballs對我也很重要。

回答

8

那麼,至少,您必須下載歸檔的部分直到包括要提取的文件的壓縮數據。這表明以下解決方案:打開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); 

這是當然的,未經測試。

+0

謝謝;這似乎工作正常(酒吧小錯誤),但不幸的是,這不能處理任何東西,但zip檔案。 – Oak 2010-06-27 07:21:45

+3

嗯,你爲什麼認爲它叫做'ZipInputStream'? ;-)如果你環顧網絡,你可能會找到一個'TarInputStream',你可以使用大致相同的方式 - 或者,如果不是,你可以編寫自己的。這很容易,因爲tar文件沒有壓縮,它基本上只是每個文件的頭文件,後面是文件數據。 (維基百科對格式有描述)對於gzip tar檔案,Java的標準庫有一個'GZIPInputStream',你可以使用tar流。 – 2010-06-27 19:59:56

+0

確實,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

0

我不確定是否有辦法從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); 
    } 
} 
+0

不幸的是,我不是託管這些文件的人......但這是一個很好的觀點。 – Oak 2010-06-28 07:34:46

5

相反,其他的答案,我會喜歡指出ZIP條目是單獨壓縮的,所以(理論上)你不需要下載超過目錄和條目本身的東西。服務器需要支持Range HTTP標頭才能正常工作。

標準Java API僅支持從本地文件和輸入流讀取ZIP文件。據我所知,沒有規定從隨機訪問遠程文件中讀取。

由於您使用的是TrueZip,我建議使用Apache HTTP Client實現de.schlichtherle.io.rof.ReadOnlyFile並使用它創建一個de.schlichtherle.util.zip.ZipFile

這不會爲壓縮的TAR歸檔提供任何優勢,因爲整個歸檔壓縮在一起(不僅僅是使用InputStream並在您輸入時將其殺死)。

2

由於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. 
    ... 
} 
相關問題