java.net.URLConnection.guessContentTypeFromStream и text / plain - PullRequest
6 голосов
/ 14 декабря 2010

All

Я пытаюсь идентифицировать простые текстовые файлы с окончаниями строк Mac и внутри InputStream беззвучно преобразовывать их в окончания строк Windows или Linux (действительно важная часть - это символ LF). В частности, я работаю с несколькими API, которые принимают InputStreams и не могут найти \ n как символы новой строки.

Иногда я получаю двоичные файлы. Очевидно, что файл, который не является текстовым, не должен выполнять эту замену, потому что значение, которое, как оказалось, соответствует \ r, очевидно, не может молча сопровождаться \ n без искажения вещей.

Я пытаюсь использовать java.net.URLConnection.guessContentTypeFromStream и выполняю только преобразования конечной строки, если тип является text / plain. К сожалению, "text/plain", похоже, не в гамме возвращаемых значений; все, что я получаю, это null для моих текстовых файлов, и, возможно, небезопасно предполагать, что все неопознаваемые файлы могут быть изменены.

Какую лучшую библиотеку (желательно в общедоступном репозитории Maven и с открытым исходным кодом) я могу использовать для этого? В качестве альтернативы, как я могу сделать угадайку ContentTypeFromStream работать для меня? Я знаю, что описываю опасное по своей природе приложение, и ни одно решение не может быть идеальным, но я должен просто считать «ноль» вероятным «текстом / простым текстом», и мне просто нужно самому написать больше кода, чтобы найти доказательства того, что это не так. «т

1 Ответ

2 голосов
/ 14 декабря 2010

Мне кажется, что вы просите определить, является ли файл текстовым или нет.Учитывая это, есть решение здесь , которое кажется правильным:

Конечно, он говорит о Unix, Bash и Perl, но концепция та же:

Если вы не проверяете каждый байт файла, вы не получите 100%.И есть большой удар производительности при проверке каждого байта.Но после некоторых экспериментов я остановился на алгоритме, который работает для меня.Я проверяю первую строку и объявляю файл двоичным, если у меня есть хотя бы один нетекстовый байт.Кажется, это немного провисает, я знаю, но мне, кажется, это сходит с рук.

РЕДАКТИРОВАТЬ # 1: Если остановиться на этом типе решения, кажется, что разумным подходом было бы убедиться, что файл не содержит не-ascii символов (если вы не имеете дело с файлами, которые не являются английскими ... это другое решение).Это можно сделать, проверив, не совпадает ли содержимое файла в виде строки:

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

РЕДАКТИРОВАТЬ # 2 Вы можете попробовать это как свое регулярное выражение или что-то близкое к этому.Тем не менее, я признаю, что он может использовать некоторые уточнения.

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