java.net.URLConnection.guessContentTypeFromStream和text/plain

Ada*_*erg 6 java text urlconnection mime-types

所有,

我试图识别带有Mac行结尾的纯文本文件,并在InputStream中静默地将它们转换为Windows或Linux行结尾(重要的部分是LF字符,真的).具体来说,我正在使用几个采用InputStreams的API,并且很难锁定以寻找\n作为换行符.

有时,我得到二进制文件.显然,一个不像文本的文件不应该进行这种替换,因为碰巧对应于\ r的值显然不能静默地跟随\n而不会严重损坏事物.

我试图使用java.net.URLConnection.guessContentTypeFromStream并仅在类型为text/plain时执行endline转换.不幸的是,"text/plain"它似乎没有回归价值; 我得到的只是null我的平面文本文件,并且假设所有无法识别的文件都可以修改可能并不安全.

我可以使用哪个更好的库(最好是在公共Maven存储库和开源中)来执行此操作?或者,我如何让guessContentTypeFromStream为我工作?我知道我正在描述一个本质上危险的应用程序,并且没有任何解决方案可以完美,但我应该将"null"视为"text/plain",我只需要自己编写更多代码来寻找证据证明它不是"T?

jav*_*y79 2

在我看来,您要求的是确定文件是否是文本文件。鉴于此,这里有一个似乎正确的解决方案:

当然,他谈论的是 unix、bash 和 perl,但概念是相同的:

除非你检查文件的每个字节,否则你不会得到 100% 的结果。检查每个字节会对性能造成很大影响。但经过一些实验,我确定了一种适合我的算法。我检查第一行,如果遇到一个非文本字节,则将文件声明为二进制文件。我知道,这似乎有点懈怠,但我似乎还是侥幸逃脱了。

编辑 #1:
扩展这种类型的解决方案,似乎一个合理的方法是确保文件不包含非 ASCII 字符(除非您正在处理非英语文件......这是另一个解决方案)。这可以通过检查字符串形式的文件内容是否与此不匹配来完成:

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

编辑 #2
您可能想尝试将其作为您的正则表达式或类似的东西。不过,我承认它可能需要一些改进。

".*(?:\\p{Print}|\\p{Space})+.*"
Run Code Online (Sandbox Code Playgroud)