2010-12-14 87 views
6

Tous,java.net.URLConnection.guessContentTypeFromStream et text/plain

Je suis en train d'identifier des fichiers texte avec des fins de ligne Mac et, à l'intérieur d'un InputStream, les convertir en silence à des fins de ligne Windows ou Linux (l'importante la partie est le personnage de LF, vraiment). Plus précisément, je travaille avec plusieurs API qui utilisent InputStreams et sont verrouillées pour rechercher \ n en tant que nouvelles lignes.

Parfois, j'obtiens des fichiers binaires. Évidemment, un fichier qui n'est pas textuel ne devrait pas avoir cette substitution, parce que la valeur qui correspond à \ r ne peut évidemment pas être suivie silencieusement par \ n sans mal gérer les choses.

Je tente d'utiliser java.net.URLConnection.guessContentTypeFromStream et d'effectuer uniquement des conversions finales si le type est texte/brut. Malheureusement, "text/plain" ne semble pas être dans sa gamme de valeurs de retour; tout ce que je reçois est null pour mes fichiers texte plats, et il est peut-être pas sûr de supposer que tous les fichiers non identifiables peuvent être modifiés. Quelle meilleure bibliothèque (de préférence dans un référentiel public Maven et open-source) puis-je utiliser pour cela? Sinon, comment puis-je faire guessContentTypeFromStream pour moi? Je sais que je suis en train de décrire une application intrinsèquement dangereuse et qu'aucune solution ne peut être parfaite, mais devrais-je simplement traiter "null" comme étant "texte/plaine" et j'ai simplement besoin d'écrire moi-même plus de code 't?

+2

+1 pour «gamut». – skaffman

Répondre

2

Il me semble que ce que vous demandez est de déterminer si un fichier est textuel ou non. Étant donné que, il y a une solution here qui semble droite:

Certes, il parle unix, bash et Perl, mais le concept est le même:

À moins que vous inspectez chaque octet du fichier , vous n'allez pas obtenir ceci 100%. Et il ya une grande performance frappé avec inspecter chaque octet. Mais après quelques expériences, je me suis installé sur un algorithme qui fonctionne pour moi. Je examiner la première ligne et déclarer le fichier être binaire si je rencontre même un octet non-texte. Il semble un peu mou, je sais, mais il me semble que je m'en sors avec .

EDIT # 1:
L'expansion de ce type de solution, cela semble une approche raisonnable serait que le fichier ne contient pas de caractères non-ascii (sauf si vous avez affaire à des fichiers qui ne sont pas -Anglais ... c'est une autre solution). Cela pourrait se faire en vérifiant si le contenu du fichier en tant que chaîne ne correspond pas:

// -- uses commons-io 
String fileAsString = FileUtils.readFileToString(new File("file-name-here")); 
boolean isTextualFile = fileAsString.matches(".*\\p{ASCII}+.*"); 

EDIT # 2
Vous pouvez essayer cela comme votre regex, ou quelque chose d'approchant. Cependant, je vais admettre qu'il pourrait probablement utiliser un peu d'affinage.

".*(?:\\p{Print}|\\p{Space})+.*" 
+0

J'allais utiliser une approche similaire à celle-ci si tout le reste échouait, sauf beaucoup moins gracieusement qu'une regex. (inspection octet par octet, ici je viens!) Au lieu d'une ligne, j'utiliserai probablement un nombre de caractères fixe, surtout pour ne pas risquer un dépassement de ma position de marque (...) sur mon BufferedReader.C'est une classe de personnage induisant des maux de tête, cependant; Quelle est la forme Java, pour ceux d'entre nous qui ne parlent pas Perl? –

+1

Je me demande comment cela agit sur les fichiers texte avec une nomenclature Unicode. – BalusC

+0

Les expressions régulières spécifiées étaient un peu trop tolérantes, mais en supprimant le début et la fin. * (Nous voulons que les caractères en dehors de la classe soient disqualifiants!) L'ont fait. Merci. –