我想验证路径中的给定文件是文本文件类型,即不是二进制文件,即人类可读。我猜读第一个字符,并检查每个字符:
- isAlphaNumeric
- 牵手
- isSeparator
- isOctetCharacter ? ?
但是将所有这些测试方法与and结合:[…]和:[…]而且:[]]似乎不太健谈。有什么更优雅的方式吗?
(这里有一个Python版本如何使用Python识别二进制和文本文件?这可能是有用的,但语法和实现看起来像c)
只能启发式;你永远不可能真正确定……
对于ascii,可以这样做:
|isPlausibleAscii numChecked|
isPlausibleAscii :=
[:char |
((char codePoint between:32 and:127)
or:[ char isSeparator ])
].
numChecked := text size min: 1024.
isPossiblyText := text from:1 to:numChecked conform: isPlausibleAscii.
对于unicode (UTF8 ?),事情变得更加困难;然后你可以尝试转换。如果有转换错误,假设是二进制。
PS:如果没有from:to: comply:,替换为(copyFrom:to:) comply:
PPS:如果没有,试试allSatisfy:
所有文本都包含比您期望在二进制文件中看到的更多的空间,并且一些编码(UTF16/32)将包含许多通用语言的0。一个简单的解决方案是在Standard/MultiByte-FileStream的方法中隐藏血色细节,#isProbablyText可能是一个不错的选择。
它基本上会做以下事情:-存储当前状态,如果你打算以后使用它,重置为启动(设置Latin1转换器,如果你使用MultiByteStream)
-
遍历N个字符(其中N是合适的数字)
-
遇到不可打印的ascii字符?它可能是二进制的,所以返回false。(不是一个特殊的选择器,使用一个映射,在字符上实现一个新方法或其他东西)
-
酌情增加2个计数器,一个用于空格字符,另一个用于零字符。
-
如果循环结束,返回是否有一个计数器已经读取了统计上显著的量
TLDR;使用一个方法来隐藏血腥的细节,否则它几乎是一样的。