2010-10-23 4 views
4

Je voudrais déterminer le type d'un fichier (généralement UTF-8) en lisant la première partie du fichier et en analysant le contenu. (Le type est spécifique à ma communauté mais pas sous mon contrôle et non couvert par MIME/MediaType qui est normalement TEXT_PLAIN). J'utilise la bibliothèque « de org.restlet » sur le client pour analyser l'en-tête avecLire la première partie d'un fichier en utilisant HTTP

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

donc je sais la longueur du contenu et peut (si nécessaire et possible) estimer le nombre d'octets je télécharger pour l'analyse CLARIFICATION: Je ne peux pas utiliser le MediaType.

De la réponse 1 semble que je dois obtenir le contenu. Une question révisée serait donc:

"Puis-je obtenir partie d'un fichier en utilisant Restlet?"

REPONSE: Le code suivant fait ce que je veux. J'ai crédité @BalusC pour montrer le chemin. S'il vous plaît commenter si j'ai oublié quelque chose:

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

Nous avons découvert que vous ne pouvez pas améliorer les fichiers que vous lisez afin qu'ils incluent le type de fichier. Nous savons que nous pouvons lire un petit nombre d'octets de chaque fichier en utilisant un InputStream. Quelle est votre question? –

+0

@Tony Ennis. Je pense que vous avez répondu à ma question. Que je devrais créer un inputStream à partir de l'URL et lire un nombre d'octets. J'avais oublié le InputStream –

Répondre

6

C'est possible que si le serveur a envoyé les Accept-Ranges et Content-Range têtes avec ETag ou Last-Modified. Par exemple.

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

Le Accept-Ranges: bytes indique que le serveur prend en charge les demandes de retour une partie du contenu dans une plage d'octets spécifié. L'en-tête Content-Range vous informe sur la longueur. Les ETag et Last-Modified indiquent le fichier unique idenfier ou le dernier horodatage modifié sur la ressource derrière l'URI de la demande.

Si ces en-têtes sont présents dans la réponse, vous pouvez demander une partie de la ressource en utilisant If-Range et Range en-têtes de requête avec respectivement l'identificateur de fichier unique ou le dernier horodatage modifié et la plage d'octets désirée.

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

L'exemple ci-dessus renvoie les 100 premiers octets du fichier.

+0

Merci. Cela ressemble à ce dont j'ai besoin. Pourquoi bytes = 0-99 renvoie 100 Ko - est-ce que ça compte toujours en KB? Est-ce que cela implique que le plus petit morceau est 1 KB? –

+0

Désolé, faute de frappe :) Cela devrait être 'B'. – BalusC

0

Puisqu'il est votre contenu pourquoi ne pas simplement inclure toutes les données dont vous avez besoin dans les premiers octets de chaque fichier?

+0

désolé - je ne peux pas faire cela. Tout n'est pas généré par mon application –

+0

Puisque nous ne connaissons pas le contenu/la disposition du fichier, je ne sais pas quoi suggérer d'autre. Des méthodes existent pour lire un petit nombre d'octets à partir de fileStream. –

+0

Il semble que ces méthodes sont exactement ce que je voudrais! –

1

L'opération HEAD, telle que définie par la norme HTTP, ne renvoie aucun contenu hormis les informations d'en-tête. Ainsi, si vous envoyez une demande de tête, vous pouvez uniquement inspecter le type MIME du fichier à partir de l'en-tête de réponse HTTP.

Les informations d'en-tête peuvent être obtenues en consultant la représentation retournée de l'emballage dans une ressource client et en effectuant une demande de tête. Cela vous donne une interface de haut niveau avec le transport HTTP et vous n'avez pas besoin d'effectuer une analyse d'en-tête personnalisée.

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

Si vous voulez faire deviner le type de contenu sur le contenu réel du fichier, vous devez télécharger le contenu réel, par exemple avec une requête GET contre cette ressource. Ou, en mode REST réel, vous pouvez modéliser un paramètre de requête supplémentaire pour votre ressource qui renverrait vos méta-informations personnalisées pour ce fichier, par exemple.

http://server/file?contentType 

De la même manière, pour récupérer le contenu réel, vous pouvez obtenir une poignée sur le Stream et puis faire l'encodage deviner. Pour spécifier des plages, si elles sont prises en charge par le serveur, vous pouvez définir les plages avant de soumettre votre requête 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(); 

Assurez-vous de consommer la réponse (flux) complètement, avant de revenir.

Je vous suggère de regarder dans d'autres efforts qui vous aident à déterminer le type de contenu. Comme ici Java charset and Windows Ou http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

+0

Je n'étais pas assez clair - J'ai besoin du contenu, pas du type de média –

+0

En JavaScript, vous lisez une partie du fichier et envoyez une requête Ajax qui obtiendrait le type de contenu. –

Questions connexes