首页 > 解决方案 > 使用 rust 读取 .dfb 文件会引发无效字符错误

问题描述

我不熟悉 rust 并创建 POC 以将dbf文件转换为csv. 我正在.dbf使用 rust library dbase读取文件。

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

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

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

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),
            _ => {}
        }
    }
}

我认为^M显示了附加的字符windows。我该怎么做才能处理此错误并成功读取文件。任何帮助都感激不尽。

标签: rustdbfdbase

解决方案


对您的问题的简短回答是否定的,您将无法使用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 字段替换 memo 字段,dbfview 应该允许你这样做
  • 如果您的字段超过 255 个字节并且您可以访问运行子流程的能力(即),您可以使用可以处理其他语言的备忘录字段Command::run的库来偷偷转换它。例如,这个 nodeJS 库可以,但只读

推荐阅读