读取具有锈蚀的.dfb文件会引发无效字符错误

Sha*_*han 2 dbf dbase rust

我刚接触锈并创建POC来将dbf文件转换为csv。我正在.dbf使用rust库dbase读取文件。

问题是,当我.dbf使用dbfview创建样本文件时,代码工作正常。但是,当我使用.dbf 实时使用的文件时。我收到以下错误。

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidFieldType('M')', src/libcore/result.rs:999:5
Run Code Online (Sandbox Code Playgroud)

这是我从给定链接使用的代码。

use dbase::FieldValue;
let records = dbase::read("tests/data/line.dbf").unwrap();
for record in records {
    for (name, value) in record {
        println!("{} -> {:?}", name, value);
        match value {
            FieldValue::Character(string) => println!("Got string: {}", string),
            FieldValue::Numeric(value) => println!("Got numeric value of  {}", value),
            _ => {}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这些^M显示的字符由附加windows。我该怎么办以解决此错误并成功读取文件。任何帮助都感激不尽。

Séb*_*uld 5

对您的问题的简短回答是“否”,您将无法使用dbase-rs(或任何当前库)读取此文件,并且您很可能必须重新制作此文件以不包含备注字段。


深入了解DBF文件格式

InvalidFieldType一个备注字段-在文件库中不能处理的结构特征的错误点。我们将深入研究该文件,以找出原因,以及是否有什么可以解决的方法。

这是标头定义:

在此处输入图片说明

特别重要的是字节28(偏移量0000010,字节0C),它是一个位掩码,指示表是否包含许多可能的内容,最值得注意的是:

  • 0x01 如果文件带有关联的.cdx文件
  • 0x02 如果包含备忘录
  • 0x04 如果文件实际上是.dbc文件(数据库)

0x03,您的文件既带有关联的.cdx文件,又包含备忘录。我们知道(提前)dbase-rs不能解决问题,这种可能性似乎越来越大。

让我们继续看。从这里开始,每个字段的长度为32个字节。

这是您的字段:

在此处输入图片说明

字节0-10包含字段名称,字节11是类型。由于您要使用的库只能解析某些字段,因此我们只关心字节11。

按照库可以解析的顺序显示:

  • [x] CALL_ID(整数)
  • [x] CONTACT_ID(整数)
  • [x] CALL_DATE(日期时间)
  • [x]主题(字符[])
  • []注意(备忘)

最后一个领域是有问题的领域。在库本身中,不支持此字段类型,因此会产生一个Error,您正尝试这样做unwrap()。这是您的错误的根源。

两种解决方法:

  • “长”方式是修补库以处理备注字段。这听起来很简单,但实际上并非如此。由于备忘录存储在另一个文件(通常是dbt同一文件夹中的文件)中,因此您将必须使该库读取两个文件并引用两个文件。备注类型本身的重点是在一个字段中存储超过255个字节的数据。您是唯一能够评估这项工作是否值得努力的人。
  • 如果您的数据小于255个字节,则可以将该注释字段替换为char字段,并且dbfview应该允许您执行此操作
  • 如果您的字段长度超过255个字节,并且可以运行子流程(例如Command::run),则可以使用可以处理另一种语言的备注字段的库来对其进行潜行转换。例如,此nodeJS库可以但为只读