Чтение первой части файла с использованием HTTP - PullRequest
4 голосов
/ 23 октября 2010

Я бы хотел определить тип файла (обычно UTF-8), прочитав первую часть файла и проанализировав его содержимое. (Тип является специфическим для моего сообщества, но не под моим контролем и не покрывается MIME / MediaType, который обычно является TEXT_PLAIN). Я использую библиотеку «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;
}

Ответы [ 3 ]

6 голосов
/ 23 октября 2010

Это возможно, только если сервер отправил заголовки Accept-Ranges и Content-Range вместе с ETag или Last-Modified.Например,

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

Accept-Ranges: bytes указывает, что сервер поддерживает запросы, возвращающие частичное содержимое в указанном диапазоне байтов.Заголовок Content-Range сообщает о длине.ETag и Last-Modified указывают уникальный идентификатор файла или последнюю измененную временную метку на ресурсе за URI запроса.

Если эти заголовки присутствуют в ответе, вы можете запросить часть ресурсаиспользуя If-Range и Range заголовки запроса с соответственно уникальным идентификатором файла или последней измененной отметкой времени и желаемым диапазоном байтов.Пример возвращает первые 100 байтов файла.

1 голос
/ 23 октября 2010

операция HEAD, как определено стандартом HTTP, не возвращает никакого контента, кроме информации заголовка. Поэтому, если вы отправляете запрос заголовка, вы можете только проверить MIME-тип файла из заголовка ответа HTTP.

Информация заголовка может быть получена путем просмотра Представления, возвращенного после его оборачивания в 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 и Windows Или http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

0 голосов
/ 23 октября 2010

Поскольку это ваш контент, почему бы просто не включить все необходимые данные в первые несколько байтов каждого файла?

...