2010-10-23 68 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

相关问题