我该如何确定一个文件(或一组文件)是用什么数据库格式创建的(在Delphi中)?

9

我有许多由不同程序创建的数据文件。有没有办法确定用于创建数据文件的数据库及其版本。

例如,我想确定哪些文件是由Microsoft Access,dBASE,FileMaker,FoxPro,SQLite或其他程序创建的。

我只是想快速扫描文件,并显示有关它们的信息,包括源数据库和版本。

供参考,我正在使用Delphi 2009。


3
你肯定知道文件扩展名。另外,你也肯定知道世界上很多程序根本不使用数据库文件格式,并且私有二进制文件格式的数量基本上是无法计算的。 - Warren P
@Warren:我特别关注家谱软件。它们倾向于在程序中使用数据库驱动程序,但将数据保存到磁盘上作为具有自己专有扩展名的项目文件。例如,我将使用DISQLite3,并将我的.bhp文件保存为SQLite格式。 - lkessler
但我期望,这些“重新命名”的数据库文件通常不是以它们的“本地”格式存在。我认为它们经常被封装到一个更大的结构(“容器”)中,其中包含一些其他(非DB)信息和可能的压缩。至少我在我的项目中是这样做的。 - Andreas
3个回答

10
首先,检查文件扩展名。查看相应的维基百科文章或其他网站。
然后,您可以从所谓的“签名”中猜测文件格式。
这主要是前几个字符的内容,能够识别文件格式。
您可以在Gary Kessler非常好的网站上找到最新的列表。
例如,这里是我们的框架如何从文件内容中识别MIME格式,在服务器端进行:
function GetMimeContentType(Content: Pointer; Len: integer;
  const FileName: TFileName=''): RawUTF8;
begin // see http://www.garykessler.net/library/file_sigs.html for magic numbers
  result := '';
  if (Content<>nil) and (Len>4) then
    case PCardinal(Content)^ of
    $04034B50: Result := 'application/zip'; // 50 4B 03 04
    $46445025: Result := 'application/pdf'; //  25 50 44 46 2D 31 2E
    $21726152: Result := 'application/x-rar-compressed'; // 52 61 72 21 1A 07 00
    $AFBC7A37: Result := 'application/x-7z-compressed';  // 37 7A BC AF 27 1C
    $75B22630: Result := 'audio/x-ms-wma'; // 30 26 B2 75 8E 66
    $9AC6CDD7: Result := 'video/x-ms-wmv'; // D7 CD C6 9A 00 00
    $474E5089: Result := 'image/png'; // 89 50 4E 47 0D 0A 1A 0A
    $38464947: Result := 'image/gif'; // 47 49 46 38
    $002A4949, $2A004D4D, $2B004D4D:
      Result := 'image/tiff'; // 49 49 2A 00 or 4D 4D 00 2A or 4D 4D 00 2B
    $E011CFD0: // Microsoft Office applications D0 CF 11 E0 = DOCFILE
      if Len>600 then
      case PWordArray(Content)^[256] of // at offset 512
        $A5EC: Result := 'application/msword'; // EC A5 C1 00
        $FFFD: // FD FF FF
          case PByteArray(Content)^[516] of
            $0E,$1C,$43: Result := 'application/vnd.ms-powerpoint';
            $10,$1F,$20,$22,$23,$28,$29: Result := 'application/vnd.ms-excel';
          end;
      end;
    else
      case PCardinal(Content)^ and $00ffffff of
        $685A42: Result := 'application/bzip2'; // 42 5A 68
        $088B1F: Result := 'application/gzip'; // 1F 8B 08
        $492049: Result := 'image/tiff'; // 49 20 49
        $FFD8FF: Result := 'image/jpeg'; // FF D8 FF DB/E0/E1/E2/E3/E8
        else
          case PWord(Content)^ of
            $4D42: Result := 'image/bmp'; // 42 4D
          end;
      end;
    end;
  if (Result='') and (FileName<>'') then begin
    case GetFileNameExtIndex(FileName,'png,gif,tiff,tif,jpg,jpeg,bmp,doc,docx') of
      0:   Result := 'image/png';
      1:   Result := 'image/gif';
      2,3: Result := 'image/tiff';
      4,5: Result := 'image/jpeg';
      6:   Result := 'image/bmp';
      7,8: Result := 'application/msword';
      else begin
        Result := RawUTF8(ExtractFileExt(FileName));
        if Result<>'' then begin
          Result[1] := '/';
          Result := 'application'+LowerCase(Result);
        end;
      end;
    end;
  end;
  if Result='' then
    Result := 'application/octet-stream';
end;

您可以使用GAry Kessler列表中的类似函数。


太好了!那正是我想知道的。Gary Kessler的页面(与我无关)也是一个很好的参考。 - lkessler

2

有许多数据库引擎,拥有数百(如果不是数千)个版本和格式。(二进制、CSV、XML...)其中许多都是加密的,以保护内容。识别每个数据库和每个格式几乎是“不可能”的,并且这是一个不断变化的主题。

因此,首先您必须将任务限制在要扫描的数据库引擎列表上。这就是我会做的事情...


好的。如果我从我给出的列表开始,有什么最好的方法来识别它们?如果还有其他常用且易于识别的项目,那么我可以添加它们。也许已经有一个Delphi组件可以做到这一点了? - lkessler
我非常怀疑是否有一种工具可以识别“任何数据库文件”。没有共同的特征可供使用,您必须将所有可能的数据库访问库组合成一个超级库来确保。当文件是特定类型但已损坏时,您的工具应该怎么做?您的问题定义不清楚,或者说,最终无法回答。 - Warren P

2
首先,我不认为您在“快速扫描”中能够做得比提供“可能的格式”更多。此外,很难想象任何快速技术都能够可靠地完成这项工作。
DBASE文件通常使用扩展名.dbf。FoxPro和Clipper使用了dBase文件格式的变体。维基百科将这些记录为xBase。任何能够打开dBase文件的dBase库也可能能够(a)通过打开该文件显示它是真正的dBase文件,并且(b)允许您查看所使用的xBase文件格式的支持变体。
Access文件通常使用.mdb文件格式,但可以使用密码加密。您可能可以编写自己的库来将内部内容明确标识为“Jet数据库引擎”(Access使用的内部文件类型),但不能读取内容,但我怀疑除非破解密码,否则您无法可靠地完成这项工作。
FileMaker文件可以有许多文件扩展名,它们的内部文件格式没有很好的文档记录。根据维基百科,.fm、.fp3、.fp5和.fp7是常见的文件扩展名。你将会遇到与Access类似的“密码”问题,因为FileMaker数据库也有密码保护。我不知道除了通过ODBC之外,在Delphi中读取FileMaker文件的其他方法,即使通过ODBC,我认为你也不能提供一个由ODBC驱动的“全能读取器”,因为在通过ODBC读取之前,需要仔细设置并了解源文件以便成为ODBC数据源。浏览/发现不是ODBC支持的阶段。
SQLite文件可以具有任何文件扩展名。尝试检测它的最简单方法是使用SQLite加载/打开文件,并查看是否打开。
其余的列表几乎是无限的,技术是相同的。只需将更多的数据库引擎和访问层库添加到你的Katamari Damaci数据库检测工具中。
如果你想从旧的数据库格式开始,我建议使用BDE(古老的,但是嘿,你谈论的是古老的东西),再加上ADO,尝试自动检测和打开文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接