Leggendo la prima parte di un file utilizzando HTTP
Domanda
Vorrei determinare il tipo di un file (in genere UTF-8) leggendo la prima parte del file e l'analisi del contenuto. (Il tipo è specifico per la mia comunità, ma non sotto il mio controllo e non coperti da MIME / MediaType che normalmente è TEXT_PLAIN). Sto usando la libreria 'org.restlet' sul client per analizzare l'intestazione con
Request request = new Request(Method.HEAD, url);
quindi so che il contenuto di lunghezza e può (se necessario e possibile) stimare il numero di byte devo scaricare per l'analisi
PRECISAZIONE: non posso usare il MediaType. Dalla risposta 1 sembra che ci siano per ottenere il contenuto. Una domanda riveduta sarebbe quindi:
"Can I Get parte di un file utilizzando Restlet?"
RISPOSTA: Il seguente codice fa quello che voglio. Ho accreditato @BalusC per mostrare la via. Si prega di commento, se ho perso qualcosa:
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;
}
Soluzione
Questo è possibile solo se il server ha inviato il Accept-Ranges
e Content-Range
intestazioni con ETag
o Last-Modified
. Per es.
Accept-Ranges: bytes
Content-Range: bytes 0-1233/1234
ETag: file.ext_1234_1234567890
Il Accept-Ranges: bytes
indica che il server supporta le richieste di ritorno contenuto parziale in un intervallo di byte specificato. Le informa intestazione Content-Range
circa la lunghezza. Il ETag
e Last-Modified
indicano l'idenfier unico file o l'ultimo timestamp modifica per la risorsa dietro l'URI della richiesta.
Se queste intestazioni sono presenti nella risposta, allora è possibile richiedere una parte della risorsa utilizzando If-Range
e Range
intestazioni di richiesta con, rispettivamente, l'identificatore unico file o l'ultimo timestamp modificato e l'intervallo di byte desiderato.
If-Range: file.ext_1234_1234567890
Range: bytes=0-99
L'esempio precedente restituisce i primi 100 byte del file.
Altri suggerimenti
l'operazione HEAD, come definito dallo standard HTTP non restituisce alcun contenuto a parte le informazioni di intestazione. Quindi, se si sta inviando una richiesta di testa, si potrebbe esaminare solo il tipo MIME del file dalla intestazione della risposta HTTP.
Le informazioni di intestazione può essere ottenuto guardando Rappresentanza tornato da avvolgendolo in un ClientResource e l'esecuzione di una richiesta di testa. Questo vi dà un'interfaccia di alto livello per il trasporto HTTP e non c'è bisogno di fare header personalizzato di analisi.
ClientResource resource = new ClientResource(url);
Representation representation = resource.head();
representation.getMediaType(); // returns the Media Type
Se si vuole fare il tipo di contenuto indovinare sul contenuto effettivo del file, si avrebbe bisogno di scaricare il contenuto effettivo, ad esempio con una richiesta GET contro quella risorsa.
O in puro stile REST si potrebbe modellare un parametro di query in più per la risorsa che restituire la tua meta informazioni personalizzate per quel file, per es.
http://server/file?contentType
In modo simile, per recuperare il contenuto effettivo, si potrebbe ottenere una maniglia sulla Stream e poi fare la codifica indovinare.
Representation representation = resource.get();
InputStream stream = representation.getStream();
Per specificare gli intervalli, se supportato dal server, è possibile impostare gli intervalli, prima di presentare la richiesta GET.
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();
Assicurarsi che si consuma la risposta (stream) completamente, prima di tornare.
vi suggerisco dovrebbe guardare in altre iniziative che consentono di determinare il tipo di contenuto. Come qui Java charset e Windows O http://glaforge.free.fr/wiki/index.php?wiki = GuessEncoding
Dal momento che è suo sito web perché non basta includere tutti i dati necessari nei primi byte di ogni file?