如何使用Smalltalk识别二进制文件和文本文件



我想验证路径中的给定文件是文本文件类型,即不是二进制文件,即人类可读。我猜读第一个字符,并检查每个字符:

  • 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;使用一个方法来隐藏血腥的细节,否则它几乎是一样的。

最新更新