6

All,

I am trying to identify plain text files with Mac line endings and, inside an InputStream, silently convert them to Windows or Linux line endings (the important part is the LF character, really). Specifically, I'm working with several APIs that take InputStreams and are hard-locked to looking for \n as newlines.

Sometimes, I get binary files. Obviously, a file that isn't text-like shouldn't have this substitution done, because the value that happens to correspond to \r obviously can't silently be followed by a \n without mangling things badly.

I am attempting to use java.net.URLConnection.guessContentTypeFromStream and only performing endline conversions if the type is text/plain. Unfortunately, "text/plain" doesn't seem to be in its gamut of return values; all I get is null for my flat text files, and it's possibly not safe to assume all unidentifiable files can be modified.

What better library (preferably in a public Maven repository and open-source) can I use to do this? Alternatively, how can I make guessContentTypeFromStream work for me? I know I'm describing an inherently hazardous application and no solution can be perfect, but should I just treat "null" as likely to be "text/plain" and I simply need to write more code myself to look for evidence that it isn't?

4

1 に答える 1

2

あなたが求めているのは、ファイルがテキストかどうかを判断することだと私には思えます。それを考えると、ここに正しいと思われる解決策があります:

確かに、彼は unix、bash、perl について話していますが、コンセプトは同じです。

ファイルのすべてのバイトを検査しない限り、この 100% を取得することはできません。また、すべてのバイトを検査すると、パフォーマンスが大幅に低下します。しかし、いくつかの実験の後、私は自分に合ったアルゴリズムに落ち着きました。最初の行を調べて、テキスト以外のバイトが 1 つでもあれば、そのファイルがバイナリ ファイルであると宣言します。少したるんでいるように見えますが、うまくいくようです。

編集#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})+.*"
于 2010-12-14T20:39:14.203 に答える