簡體   English   中英

GZIPInputStream:從解壓縮的文件中讀取前n個字節

[英]GZIPInputStream: Read first n bytes from decompressed file

我有成千上萬個通過HTTP訪問的GZIP文件。 每個文件的大小上限為幾百MB。 我需要從這些壓縮文件中的文件讀取前幾千字節(標頭)。

這是我目前的方法:

URL url = new URL("http://example.com/file123.gz");
DataInputStream ds = new DataInputStream(new GZIPInputStream(url.openStream()));
byte[] header = new byte[5760];
ds.readFully(header);

我需要做的是從此GZIP文件中的文件中下載前5760個字節,但是我不希望Java下載整個文件(通常多於幾個MB)。

我的問題是-Java是先下載整個GZIP文件然后解壓縮,還是只下載必要的數據量來填充byte[5760]緩沖區? 如何找到從HTTP服務器實際下載了多少數據?

Java是先下載整個GZIP文件然后解壓縮,還是下載所需數量的數據以填充byte [5760]緩沖區?

它更接近后者。 Java不會先讀取整個文件。 相反, url.openStream()給您一個“套接字流”,該套接字直接從套接字讀取數據。

內核端套接字數據結構中可能緩沖了一些數據, GZIPInputStream可能緩沖了一些數據。 但這絕對是一個有限的數目。 因此,服務器可能會發送比應用程序實際消耗更多的數據,但不太可能發送整個(兆字節大小)的文件。

如何找到從HTTP服務器實際下載了多少數據?

這很難衡量,甚至很難定義。 根據上下文,您似乎對服務器發送的數量確實很感興趣。 唯一實際的測量方法是在服務器端,甚至很難。 (如果您真的不需要找出這個,我建議您不要麻煩嘗試...)

您無法指定實際將下載多少數據。

滿足您的請求的Web服務器將打開請求的文件,並通過tcp連接發送全部內容(以http響應標頭開頭)。

這意味着整個文件將被發送給您,除了在正確的時間關閉基礎連接之外,您將無法執行任何操作,但這將不容易實現,尤其是無法可靠地工作。 這意味着:您從inputstream中讀取了5760字節(此時,它已經包含了超過5760字節!),然后關閉流和連接-但這並不意味着在此期間接收到更多數據

要弄清您實際收到了多少,您必須完全閱讀輸入流並檢查其長度。

如果Web服務器支持字節范圍請求,則您可以告訴它僅下載第一個(例如)10kB壓縮數據(以確保在解壓縮時至少獲得5760字節)。

URL url = new URL("http://example.com/file123.gz");
URLConnection connection = url.openConnection();
connection.setRequestProperty("Range", "bytes=0-9999");
DataInputStream ds = new DataInputStream(
                         new GZIPInputStream(connection.getInputStream()));
byte[] header = new byte[5760];
ds.readFully(header);

您可能需要捕獲在此過程中引發的任何異常,然后在沒有范圍標頭的情況下重試(盡管不了解它的服務器應該無論如何都要發送整個文件)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM