在Crystal中,如何判断文件是文本还是二进制文件?

时间:2018-05-21 21:18:50

标签: crystal-lang

如果您有2个文件,一个文本和另一个二进制文件,是否可以确定哪个是文本文件,哪个是使用Crystal的二进制文件?

2 个答案:

答案 0 :(得分:5)

您可以使用Magic Numbers来检测二进制文件,否则它可能是纯文本文件。

  

是否可以确定哪个是文本文件,哪个是使用Crystal的二进制文件?

如果您认为“二进制”是ELF文件,那么您可以尝试:

def filetype(filename)
  unless File.file?(filename)
    puts "Isn't a file!"
    return
  end
  File.open(filename, "r") do |f|
    case f.gets(4)
    when "\x7FELF" then puts "Is an ELF binary file"
    # when "GIF8" then puts "Is a GIF"
    # when "\x25\x50\x44\x46" then puts "Is a PDF"
    # ... and so on
    else
      puts "Probably is a plain text file"
    end
  end
end

File.write("plain.txt", "Plain Text File")

filetype("plain.txt")   # => Probably is a plain text file
filetype("/usr/bin/ls") # => Is an ELF binary file
filetype("/dev/sda")    # => Isn't a file!

这甚至适用于非可执行的ELF文件(没有x权限)。如果要检测可执行文件,请使用File.executable?

在这里演示:https://carc.in/#/r/44a2

同样file是一个很好的命令,它使用libmagic来检测幻数并获得正确的文件类型。您也可以使用Crystal对libmagic进行一些绑定,因此您无需自己指定所有幻数。

答案 1 :(得分:1)

我想,使用原生水晶是不可能的。要确定文件的类型,需要读取文件的一部分并根据内容猜测其类型。这可能是一个棘手的部分,所以如果你需要一个相对可靠的解决方案,我建议从Crystal调用file --mime-type -b <file>并解析输出,虽然它有时也会出错。

此外,您可以使用crystal-mime分片来处理file命令的输出。