在我的程序中,用户可以加载带有链接的文件(这是一个webcrawler),但我需要验证用户选择的文件是纯文本还是其他文件(只允许纯文本)。如何检查文件是纯文本?
可以这样做吗?如果有用,我使用JFileChooser来打开文件。
编辑:
什么是从用户预期:包含URL的文本文件。
我想要避免的事情:用户从MS Word(示例)中加载MP3文件或文档。
在我的程序中,用户可以加载带有链接的文件(这是一个webcrawler),但我需要验证用户选择的文件是纯文本还是其他文件(只允许纯文本)。如何检查文件是纯文本?
可以这样做吗?如果有用,我使用JFileChooser来打开文件。
编辑:
什么是从用户预期:包含URL的文本文件。
我想要避免的事情:用户从MS Word(示例)中加载MP3文件或文档。
一个文件只是一系列的字节,没有更多的信息,你不能分辨这些字节是否应该是某些字符串编码(比如ASCII或UTF-8或ANSI-something)中的代码点或其他东西。您将不得不采取启发式方法,例如:
但是,这里有另一种解决方案:将所有您收到的文本视为文本,在需要时应用必要的转换(例如发送到Web浏览器时进行HTML编码)。只要你防止文件被解释为二进制数据(例如用户双击该文件),最糟糕的是你会产生乱码数据。
文本也是二进制数据的一种形式。
我想你要检查的是你的输入中是否有任何字符是< 32.如果你可以安全地假定你的文本是多字节编码的,那么你可以扫描整个文件并中止如果你在[0,32]范围内选择一个字节(不包括9,10,13,除了“文本”中的任何其他内容),或者最坏的情况检查空字节[谢谢,tdammers!] )。如果您可以合理地期望接收UTF-16或UTF-32编码文本,则必须更加努力。
您应该创建一个查看文件描述的过滤器,并检查文本。
如果您不想通过file extension来猜测,您可以阅读文件的第一部分。但接下来的问题将是字符编码。使用BufferedInputStream
(之前的mark()
和之后的reset()
),用编码为"ISO-8859-1"
的InputStreamReader
进行包装,并使用Character.isLetterOrDigit()
或Character.isWhitespace()
对已读取的字符进行计数,以获得典型文本内容的比率。我认为文本文件的比例应该超过80%。
您也可以尝试使用其他编码,如UTF-8,但当您的编码不是UTF-8时,您可能会遇到无效的字符问题。
我可以轻松地将图像的扩展名重命名为“.TXT”,并尝试将其加载到试图打开“文本”文件并导致其崩溃的应用程序中。 – Si8
@ SiKni8:这不是问题,一个好的应用程序在打开二进制文件时不会崩溃! –
您还可以查看是否初始字节是物料清单,这应该表明UTF文件:
- UTF-8 => 0xEF, 0xBB, 0xBF
- UTF-16 BE => 0xFE, 0xFF
- UTF-16 LE => 0xFF, 0xFE
Rossum的
可以从Java调用shell命令file -i ${filename}
,并检查输出看它是否包含像charset=binary
这样的东西。如果是这样,那么它是二进制文件。否则,它是基于文本的文件。
你可以在shell中使用file
在各种文件中玩并熟悉它。 Groovy中我会写类似
'file -i ${path/to/myfile}'.execute().getText().contains('charset=binary')
在Java中,你也可以拨打shell命令。请参阅this。
Tab,换行符和回车符<32 – tdammers
@tdammers:哎呀,好抓。好的,排除那些比赛!那么换行呢? :-) –
我可能会检查文件是否为UTF-8,假设它是文本,如果它是有效的UTF-8(可能不包括与制表符,换行符和回车符以及127之外的代码点<32)。 – MRAB