【问题标题】:Reading the first part of a file using HTTP使用 HTTP 读取文件的第一部分
【发布时间】:2010-10-23 15:22:37
【问题描述】:

我想通过读取文件的第一部分并分析内容来确定文件的类型(通常是 UTF-8)。 (该类型特定于我的社区,但不受我的控制,也不受通常为 TEXT_PLAIN 的 MIME/MediaType 覆盖)。我正在使用客户端上的“org.restlet”库来分析带有

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

所以我知道内容长度,并且可以(如果必要和可能的话)估计我应该下载多少字节进行分析

澄清:我无法使用 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;
}

【问题讨论】:

  • 我们发现您无法增强正在阅读的文件,因此它们包含文件类型。我们知道我们可以使用 InputStream 从每个文件中读取少量字节。你有什么问题?
  • @Tony Ennis。我想你已经回答了我的问题。我应该从 URL 创建一个 inputStream 并读取一些字节。我忘记了 InputStream

标签: java http restlet


【解决方案1】:

这只有在服务器发送了Accept-RangesContent-Range 标头以及ETagLast-Modified 时才有可能。例如

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 个字节。

【讨论】:

  • 谢谢。这看起来像我需要的。为什么 bytes=0-99 返回 100KB - 它总是以 KB 为单位计算吗?这是否意味着最小的块是 1 KB?
  • 对不起,错字:) 应该是B
【解决方案2】:

HTTP 标准定义的 HEAD 操作不返回除标头信息之外的任何内容。因此,如果您发送的是头请求,则只能从 HTTP 响应头中检查文件的 MIME 类型。

可以通过查看将其包装到 ClientResource 并执行头部请求返回的 Representation 来获取头部信息。这为您提供了 HTTP 传输的高级接口,您无需进行自定义标头解析。

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

如果您想对文件的实际内容进行内容类型猜测,则需要下载实际内容,例如使用针对该资源的 GET 请求。

或者以真正的 REST 方式,您可以为您的资源建模一个额外的查询参数,该参数将返回该文件的自定义元信息,例如

http://server/file?contentType

以类似的方式,要检索实际内容,您可以获取 Stream 的句柄,然后进行编码猜测。

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 Windowshttp://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

【讨论】:

  • 我不够清楚 - 我需要内容,而不是媒体类型
  • 在 JavaScript 中,您读取文件的一部分并发送将获取内容类型的 Ajax 请求。
【解决方案3】:

既然这是您的内容,为什么不在每个文件的前几个字节中包含您需要的所有数据?

【讨论】:

  • 对不起 - 我不能那样做。它不都是由我的应用程序生成的
  • 由于我们不知道文件内容/布局,我不知道还有什么建议。存在从 fileStream 读取少量字节的方法。
  • 听起来这些方法正是我想要的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 2015-05-17
  • 2012-05-28
  • 1970-01-01
  • 2019-05-23
  • 2015-07-16
相关资源
最近更新 更多