代码之家  ›  专栏  ›  技术社区  ›  benno

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

  •  57
  • benno  · 技术社区  · 16 年前

    非正式地说,我们大多数人都知道有“二进制”文件(对象文件、图像、电影、可执行文件、专有文档格式等)和“文本”文件(源代码、XML文件、HTML文件、电子邮件等)。

    一般来说,您需要知道文件的内容才能对它做任何有用的事情,并且形成这样的观点:如果编码是“二进制”或“文本”,那么这并不重要。当然,文件只存储字节数据,所以它们都是“二进制”的,“文本”在不知道编码的情况下没有任何意义。然而,谈论“二进制”和“文本”文件仍然是有用的,但为了避免用这种不精确的定义冒犯任何人,我将继续使用“恐吓”引号。

    所以,问题是,如何判断文件是“文本”还是“二进制”?更进一步地说,在类似Linux的文件系统上,您如何判断?我不知道有任何文件系统元数据指示文件的“类型”,因此,通过检查文件的内容,问题进一步变成了如何判断文件是“文本”还是“二进制”?为了简单起见,让我们将“文本”限制为可在用户控制台上打印的字符。尤其是你会怎么做 这(我认为这在这个网站上是隐含的,但我想,一般来说,指出实现这一点的现有代码是有帮助的,我应该指定),我并不真正想知道我可以使用哪些现有程序来实现这一点。

    11 回复  |  直到 12 年前
        1
  •  64
  •   0 _ Edward Ned Harvey    8 年前

    你可以使用 file 命令它对文件进行了一系列测试( man file

    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
    
        2
  •  17
  •   istvanp    7 年前

    我公司生产的电子表格软件可以读取许多二进制文件格式以及文本文件。

    我们首先看一个 magic number 我们承认这一点。如果我们无法识别所读取的任何二进制类型的幻数,那么我们将查看文件的前2K字节,看看它是否是一个幻数 UTF-8 , UTF-16 code page 主机操作系统的。如果它没有通过这些测试,我们假设它不是一个我们可以处理并抛出适当异常的文件。

        3
  •  16
  •   phihag    7 年前

    MIME type 文件的

    file --mime FILENAME
    

    速记是 file -i file -I (大写i)在macOS上(见注释)。

    如果是从 text/ ,它是文本,否则为二进制。唯一的例外是XML应用程序。您可以通过查找 +xml 在文件类型的末尾。

        4
  •  5
  •   bam    8 年前

    要列出当前目录/子目录中的文本文件名,请执行以下操作:

    $ grep -rIl ''
    

    二进制文件:

    $ grep -rIL ''
    

    要检查特定文件,请稍微修改命令:

    $ grep -qI '' FILE
    

    可以检查:

    $echo$?

        5
  •  4
  •   MSN    16 年前

    如果你只是检查整个文件,看看是否每个字符都可以用 isprint(c)

    要区分unicode文本文件, MSDN offers some great advice as to what to do .

    其要点是首先检查最多前四个字节:

    EF BB BF     UTF-8 
    FF FE        UTF-16, little endian 
    FE FF        UTF-16, big endian 
    FF FE 00 00  UTF-32, little endian 
    00 00 FE FF  UTF-32, big-endian 
    

    这将告诉您编码。那么,你会想使用 iswprint(c) 对于文本文件中的其余字符。对于UTF-8和UTF-16,您需要手动解析数据,因为单个字符可以由可变的字节数表示。另外,如果你真的是肛门,你会想使用 iswprint 如果你的平台上有这个功能。

        6
  •  3
  •   bobbogo    11 年前

    Perl有一个相当不错的启发式。使用 -B -T

    $ find . -type f -print0 | perl -0nE 'say if -f and -s _ and -T _'
    

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

        7
  •  3
  •   VDave    10 年前

    这是一个老话题,但也许有人会发现这很有用。 如果您必须在脚本中确定某个内容是否为文件,则可以简单地执行以下操作:

    if file -i $1 | grep -q text;
    then 
    .
    .
    fi
    

    这将得到文件类型,通过一个无声的grep,你可以决定它是否是一个文本。

        8
  •  3
  •   Benoit Blanchon    5 年前

    你可以用 libmagic 哪个是Unix的库版本 file

    有多种语言的包装器:

        9
  •  2
  •   dwc    16 年前

    N 文件的字节数,并查看这些字节 全部的

        10
  •  1
  •   Georg Schölly Crazy Developer    16 年前

    一个简单的检查是它是否有 \0 人物。文本文件没有它们。

        11
  •  1
  •   Steve Weet    16 年前

    这个名为magic的文件历史上存储在/etc中,尽管在某些发行版上可能存储在/usr/share中。magic文件定义文件中已知值的偏移量,然后可以检查这些位置以确定文件的类型。

    可以通过查阅相关手册页面(man magic)找到magic文件的结构和说明

    至于实现,可以在 file.c

    /* Make sure we are dealing with ascii text before looking for tokens */
        for (i = 0; i < nbytes - 1; i++) {
            if (!isascii(buf[i]) ||
                (iscntrl(buf[i]) && !isspace(buf[i]) &&
                 buf[i] != '\b' && buf[i] != '\032' && buf[i] != '\033'
                )
               )
                return 0;   /* not all ASCII */
        }