6

全部,

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

有时,我会得到二进制文件。显然,不是文本的文件不应该进行这种替换,因为恰好对应于 \r 的值显然不能在不严重破坏事物的情况下默默地跟在 \n 后面。

如果类型是文本/纯文本,我正在尝试使用java.net.URLConnection.guessContentTypeFromStream并且仅执行结束行转换。不幸的是,"text/plain"它似乎不在它的返回值范围内。我得到的只是null我的纯文本文件,假设所有无法识别的文件都可以修改可能是不安全的。

我可以使用什么更好的库(最好在公共 Maven 存储库和开源中)来执行此操作?或者,我怎样才能让 guessContentTypeFromStream 为我工作?我知道我在描述一个固有危险的应用程序,没有解决方案是完美的,但我是否应该将“null”视为可能是“text/plain”,我只需要自己编写更多代码来寻找证据证明它是不是吗?

4

1 回答 1

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}+.*" );

编辑#2
你可能想试试这个作为你的正则表达式,或者接近它的东西。不过,我承认它可能需要一些精炼。

".*(?:\\p{Print}|\\p{Space})+.*"
于 2010-12-14T20:39:14.203 回答