2010-12-14 184 views
6

所有,java.net.URLConnection.guessContentTypeFromStream和纯文本/

我试图找出纯文本文件与Mac行尾和,一个InputStream里面,默默地将它们转换为Windows或Linux行尾(重要部分是LF字符,真的)。具体来说,我正在处理几个采用InputStream的API,并将其锁定为\ n作为换行符。

有时,我会得到二进制文件。很显然,一个非文本类型的文件不应该进行这种替换,因为恰好相应于\ r的值不会在后面悄悄地跟随\ n而不会严重损坏。

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

我可以用更好的库(最好在公共Maven存储库和开源中)来做到这一点?或者,我怎么能guessContentTypeFromStream为我工作?我知道我正在描述一个固有的危险应用程序,没有解决方案可能是完美的,但是我应该把“空白”看作是“文本/纯文本”,我只需要自己编写更多的代码来寻找证据证明它不是“T?

+2

+1为“色域”。 – skaffman 2010-12-14 20:32:24

回答

2

在我看来,你问的是确定一个文件是否是文本文件。鉴于此,有一个解决方案here似乎正确:

诚然,他是在谈论UNIX,bash和perl的,但概念是相同的:

除非你检查0​​文件的每个字节,你不会100%获得这个 。有一个很大的性能 检查每个字节。但 经过一些实验后,我决定在 算法适合我。 I 检查第一行并声明 文件是二进制文件,如果我遇到一个非文本字节即使是 。这似乎有点松懈,我知道,但我似乎脱掉了 与它。

编辑#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})+.*" 
+0

我打算使用类似于如果所有其他都失败的方法,除了比正则表达式少得多的优雅。 (逐字节检查,这里我来了!)而不是一条线,我可能会使用一个固定的字符数,主要是不会冒我的BufferedReader上的标记(...)位置的溢出风险。虽然这是一个令人头痛的角色类,对于那些不会说Perl的人来说,Java表单是什么? – 2010-12-14 20:43:21

+1

我不知道这是如何作用于Unicode文本文件。 – BalusC 2010-12-14 21:09:45

+0

指定的正则表达式有些过于宽容,但是取出了前导和尾随。*(我们想让课堂外的人物失去资格!)做到了。谢谢。 – 2010-12-14 23:21:01