2010-10-23 66 views
4

我想通過讀取文件的第一部分並分析內容來確定文件的類型(通常是UTF-8)。 (該類型特定於我的社區,但不在我的控制之下,不包含在通常爲TEXT_PLAIN的MIME/MediaType中)。我使用的客戶端上的「org.restlet」庫分析與使用HTTP讀取文件的第一部分

Request request = new Request(Method.HEAD, url); 

頭,所以我知道內容長度和可以(如果有必要和可能的),估計我應該有多少個字節下載分析

CLARIFICATION:我無法使用MediaType。從答案1似乎我必須獲取內容。修改後的問題因此將是:

「我可以使用Restlet獲取文件的部分嗎?」

答案: 下面的代碼做我想要的。我已經記下了@BalusC的展示方式。請評論,如果我錯過了什麼:

public String readFirstChunk(String urlString, int byteCount) { 
    String text = null; 
    if (urlString != null) { 
     org.restlet.Client restletClient = new org.restlet.Client(Protocol.HTTP); 
     Request request = new Request(Method.GET, urlString); 
     List<Range> ranges = Collections.singletonList(new Range(0, byteCount)); 
     request.setRanges(ranges); 
     Response response = restletClient.handle(request); 
     if (Status.SUCCESS_OK.equals(response.getStatus())) { 
      text = processSuccessfulChunkRequest(response); 
     } else if (Status.SUCCESS_PARTIAL_CONTENT .equals(response.getStatus())) { 
      text = processSuccessfulChunkRequest(response); 
     } else { 
      System.err.println("FAILED "+response.getStatus()); 
     } 
    } 
    return text; 
} 

private String processSuccessfulChunkRequest(Response response) { 
    String text = null; 
    try { 
     text = response.getEntity().getText(); 
    } catch (IOException e) { 
     throw new RuntimeException("Cannot download chunk", e); 
    } 
    return text; 
} 
+0

我們發現您無法增強您正在閱讀的文件,因此它們包含文件類型。我們知道我們可以使用InputStream從每個文件讀取少量字節。你有什麼問題? – 2010-10-23 16:07:11

+0

@Tony Ennis。我想你已經回答了我的問題。我應該從URL創建一個inputStream並讀取一些字節。我忘記了InputStream – 2010-10-23 16:11:57

回答

6

,如果服務器已與ETagLast-Modified一起發送的Accept-RangesContent-Range頭只有可能。例如。

Accept-Ranges: bytes 
Content-Range: bytes 0-1233/1234 
ETag: file.ext_1234_1234567890 

Accept-Ranges: bytes表示服務器支持返回在指定的字節範圍的部分內容的請求。 Content-Range標題通知有關的長度。 ETagLast-Modified表示請求URI後面的資源上唯一的文件標識符或上次修改的時間戳。

如果這些報頭中存在的響應,那麼可以要求使用If-RangeRange請求報頭分別與唯一文件標識符或最後修改的時間戳和所需的字節範圍的資源的一部分。

If-Range: file.ext_1234_1234567890 
Range: bytes=0-99 

上面的例子返回文件的前100個字節。

+0

謝謝。這看起來像我所需要的。爲什麼bytes = 0-99會返回100KB - 它總是以KB計算嗎?這是否意味着最小的塊是1 KB? – 2010-10-23 17:00:30

+0

對不起,錯字:)它應該是'B'。 – BalusC 2010-10-23 17:10:46

0

因爲這是你的內容,爲什麼不只是包括所有你在每個文件的前幾個字節需要的數據?

+0

抱歉 - 我無法做到這一點。這不是全部由我的應用程序生成 – 2010-10-23 16:02:15

+0

由於我們不知道文件內容/佈局,我不知道還有什麼建議。存在用於從fileStream中讀取少量字節的方法。 – 2010-10-23 16:05:30

+0

聽起來像這些方法正是我想要的! – 2010-10-23 16:08:53

1

由HTTP標準定義的HEAD操作不會返回除標題信息之外的任何內容。因此,如果您發送頭請求,則只能從HTTP響應頭中檢查文件的MIME類型。

頭部信息可以通過查看將它包裝到ClientResource並執行頭部請求所返回的表示形式來獲得。這爲您提供了HTTP傳輸的高級接口,您不需要執行自定義標頭解析。

ClientResource resource = new ClientResource(url); 
Representation representation = resource.head(); 
representation.getMediaType(); // returns the Media Type 

如果你想要做的內容類型的猜測上的文件的實際內容,你需要下載的實際內容,例如使用針對資源的GET請求。

或者以真正的REST方式,您可以爲您的資源建模一個額外的查詢參數,該參數將返回該文件的自定義元信息,例如,

http://server/file?contentType 

以類似的方式,檢索實際內容,你可以得到一個流的句柄,然後做你的編碼猜測。

Representation representation = resource.get(); 
InputStream stream = representation.getStream(); 

要指定範圍(如果服務器支持),可以在提交您的獲取請求之前設置範圍。

List<Range> ranges = new ArrayList<Range>(); 
ranges.add(new Range(0,100)); // this would request the first 100 bytes 
resource.setRanges(ranges); 
Representation representation = resource.get(); 

確保在返回之前完全消耗響應(流)。

我建議你看看可以幫助你確定內容類型的其他工作。 喜歡這裏Java charset and Windows 或者http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

+0

我還不夠清楚 - 我需要的是內容,而不是媒體類型 – 2010-10-23 16:07:17

+0

在JavaScript中,您讀取文件的一部分併發送Ajax請求,以獲取內容類型。 – 2010-10-23 16:21:15

相關問題