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

时间:2011-08-12 03:46:10

标签: smalltalk squeak pharo file-type visualworks

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

  • isAlphaNumeric
  • isSpecial
  • 并将isSeparator
  • isOctetCharacter ???

但加入所有这些测试方法和:[...和:[...和:[]]]似乎不是很小。有什么更优雅的建议吗?

(这里有一个Python版本How to identify binary and text files using Python?可能很有用,但语法和实现看起来像C。)

2 个答案:

答案 0 :(得分:1)

只有启发式;你永远不能确定......

对于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:如果你没有:to:conform:,则替换为(copyFrom:to :)符合:

PPS:如果您没有符合:,请尝试allSatisfy:

答案 1 :(得分:0)

所有文本都包含比您希望在二进制文件中看到的空间更多的空间,并且某些编码(UTF16 / 32)将包含许多用于常见语言的0。 一个小小的解决方案是隐藏Standard / MultiByte-FileStream方法中的血腥细节,#isProbablyText可能是一个不错的选择。

它基本上会做以下事情: - 如果您打算稍后使用它,请存储当前状态,重置为启动(如果您使用MultiByteStream,则设置Latin1转换器)

  • 迭代N个下一个字符(其中N是一个合适的数字)

  • 遇到不可打印的ascii字符?它可能是二进制的,所以返回false。 (不是特殊选择器,使用地图,对角色或其他东西实施新方法)

  • 如果合适,增加2个计数器,一个用于空格字符,另一个用于零个字符。

  • 如果循环结束,则返回是否已读取其中一个计数器具有统计显着性的数量

TLDR;使用方法隐藏血腥细节,否则它几乎相同。