如何区分"二进制"和"文本"文件?

ben*_*nno 61 language-agnostic unix ascii file-format binaryfiles

非正式地,我们大多数人都知道存在"二进制"文件(目标文件,图像,电影,可执行文件,专有文档格式等)和"文本"文件(源代码,XML文件,HTML文件,电子邮件等).

通常,您需要知道文件的内容才能对其执行任何有用的操作,并且如果编码是"二进制"或"文本",则形成该视点,这并不重要.当然,文件只存储数据字节,因此它们都是"二进制",而"文本"并不意味着什么,而不知道编码.然而,谈论'二进制'和'文本'文件仍然很有用,但为了避免冒犯任何具有这种不精确定义的人,我将继续使用'恐慌'报价.

但是,有各种工具可以处理各种文件,实际上,您希望根据文件是"文本"还是"二进制"来执行不同的操作.这方面的一个例子是在控制台上输出数据的任何工具.简单的"文本"看起来很好,很有用.'二进制'数据会扰乱您的终端,并且通常无法查看.GNU grep在确定是否应该输出匹配到控制台时至少使用这种区别.

那么,问题是,如何判断文件是"文本"还是"二进制"?而且要进一步限制,你如何在类似Linux的文件系统上讲述?我不知道任何文件系统元数据指示文件的"类型",所以通过检查文件的内容,我如何判断它是"文本"还是"二进制"?为简单起见,我们将"text"限制为可在用户控制台上打印的字符.特别是你会如何实现这个?(我认为这是暗示在这个网站上,但我想一般来说,指向现有的代码,这应该是有用的,我应该指定),我不是真的在我可以使用的现有程序之后做什么这个.

nau*_*cho 62

您可以使用该file命令.它对文件(man file)进行了大量测试,以确定它是二进制还是文本.如果需要从C开始,可以查看/借用其源代码.

file README
README: ASCII English text, with very long lines

file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped
Run Code Online (Sandbox Code Playgroud)


phi*_*hag 15

您可以使用确定文件的MIME类型

file --mime FILENAME
Run Code Online (Sandbox Code Playgroud)

简写是file -i在Linux上和file -I(资本i)在macOS上(见注释).

如果以它开头text/,则为文本,否则为二进制.唯一的例外是XML应用程序.您可以通过查找+xml文件类型的末尾来匹配它们.


Joe*_*son 14

我公司制作的电子表格软件可以读取多种二进制文件格式以及文本文件.

我们首先看一下我们识别的幻数的前几个字节.如果我们不识别我们读取的任何二进制类型的幻数,那么我们查看文件的前2K字节,看它是否是UTF-8,UTF-16或编码的文本文件在主机操作系统的当前代码页中.如果它没有通过这些测试,我们假设它不是我们可以处理的文件并抛出适当的异常.


bam*_*bam 8

关键选项是这样的:

  -I     Process a binary file as if it did not contain matching data;
Run Code Online (Sandbox Code Playgroud)

其他选项:

  -r, --recursive
         Read all files under each directory, recursively;
  -l, --files-with-matches
         Suppress normal output; instead print the name of each input file from which output would normally have been printed.
  -L, --files-without-match
         Suppress normal output; instead print the name of each input file from which no output would normally have been printed.
  -q, --quiet, --silent
         Quiet; do not write anything to standard output.  Exit immediately with zero status if any match is found, even if an error was detected.
Run Code Online (Sandbox Code Playgroud)

  • 我在 dd 和 nano 生成的文件上测试了它。你的方法效果很好。我也很感兴趣为什么有人投反对票。 (3认同)

bob*_*ogo 5

Perl 有一个不错的启发式。使用-B运算符测试二进制(及其相反的-T测试文本)。这是一个列出文本文件的单行 shell:

$ find . -type f -print0 | perl -0nE 'say if -f and -s _ and -T _'
Run Code Online (Sandbox Code Playgroud)

(请注意,前面没有美元的下划线是正确的 (RTFM)。)