快速确定文件是否为 SQLite 数据库的方法

快速确定文件是否为 SQLite 数据库的方法

我正在寻找一种方法来确定包含数千个文件的文件夹中的文件类型。文件名不透露太多信息,也没有扩展名,但类型不同。具体来说,我试图确定一个文件是否是 sqlite 数据库。

使用该file命令时,每秒确定2-3个文件的类型。这似乎是解决问题的好方法,但速度太慢。

然后我尝试使用 sqlite3 打开每个文件并检查是否出现错误。这样,我每秒可以检查 4-5 个文件。好多了,但我认为可能有更好的方法来做到这一点。

答案1

每秒测试 2-3 个文件对file我来说似乎很慢。file实际上执行许多不同的测试来尝试确定文件类型。由于您正在寻找一种特定类型的文件 (sqlite),并且您不关心识别所有其他文件,因此您可以对已知的 sqlite 文件进行实验,以确定哪个测试真正识别它。然后,您可以使用该标志排除其他文件-e,并针对完整文件集运行。请参阅手册页:

 -e, --exclude testname
         Exclude the test named in testname from the list of tests made to
         determine the file type. Valid test names are:

         apptype
            EMX application type (only on EMX).
         text
            Various types of text files (this test will try to guess the
            text encoding, irrespective of the setting of the ‘encoding’
            option).
         encoding
            Different text encodings for soft magic tests.
         tokens
            Looks for known tokens inside text files.
         cdf
            Prints details of Compound Document Files.
         compress
            Checks for, and looks inside, compressed files.
         elf
            Prints ELF file details.
         soft
            Consults magic files.
         tar
            Examines tar files.

编辑:我自己尝试了一些测试。概括:

  1. file对于确定 sqlite 的测试,应用我的建议和正确的标志可以加快大约 15% 的速度。这是一些事情,但不是我预期的巨大改进。
  2. 你的文件测试真的很慢。我在标准机器上完成了 500 次,而你则完成了 2-3 次。您是否使用缓慢的硬件,或者检查巨大的文件,运行旧版本的file,或者......?
  3. 您必须保留“软”测试才能成功将文件识别为 sqlite。

对于 16MB sqlite DB 文件,我做了:

#!/bin/bash
for  i in {1..1000}
do
    file sqllite_file.db | tail > out
done

命令行上的计时:

~/tmp$ time ./test_file_times.sh; cat out

real    0m2.424s
user    0m0.040s
sys 0m0.288s
sqllite_file.db: SQLite 3.x database

尝试不同的测试排除,并假设基于单个测试做出确定,则识别该文件的是“软”(即魔术文件查找)测试。因此,我修改了file命令以排除所有其他测试:

file -e apptype -e ascii -e encoding -e tokens -e cdf -e compress -e elf -e tar sqllite_file.db | tail > out

运行 1000 次:

~/tmp$ time ./test_file_times.sh; cat out

real    0m2.119s
user    0m0.060s
sys         0m0.280s
sqllite_file.db: SQLite 3.x database

答案2

如果你看:http://www.sqlite.org/fileformat.html,SQLite 格式以字符串“SQLite format 3\000”开头。在我看来,您可以检查head -c 16文件以检查格式。我希望这比使用更通用的工具更快。

答案3

如果您查看filesqlite 文件的神奇描述,它会在文件的开头查找SQLite format 3或。** This file contains an SQLite

因此,您可以创建一个仅包含这些检查的魔术文件(并禁用@ire_and_curses 解决方案中的内置测试)或手动进行检查:

case $(head -c 31 < "$file") in
  ("** This file contains an SQLite"*) echo sqlite 2;;
  ("SQLite format 3"*) echo sqlite 3;;
esac

效率不高,因为它运行head每个文件。只需稍加努力,您就可以在 Perl 中完成此操作,在一次 Perl 调用中读取多个文件的前 31 个字节。

相关内容