仅来自 DBF 文件的备注字段 returns 使用 VFP OLE DB Provider for .NET 的几个字符

Memo field from DBF file only returns a few characters using VFP OLE DB Provider for .NET

我正在开发一个从 .DBF 数据库读取信息的 Winforms 应用程序。 我使用 VFP OLE DB Provider 进行常规查询,它工作得很好。

但我已经到了需要读取存储在 Memo 字段中的图像的地步。如果我执行常规 SELECT 查询来获取字段,我只会得到一个值为

的字符串

ÿØÿà

我认为它是 JPE 图像元数据的一部分,但显然我遗漏了一些信息。

我需要做的是从数据库中提取信息并以 PictureBox 形式显示。

这是我用来从数据库中读取信息的代码:

public DataTable SendQuery(string query)
{
    try
    {
        Conn = new OleDbConnection
        {
            ConnectionString = "Provider=vfpoledb;Data Source=C:\Data;Extended Properties=dBASE IV;Collating Sequence=machine;"
        };
        Conn.Open();

        OleDbDataAdapter adapter = new OleDbDataAdapter(query, Conn);
        DataSet ds = new DataSet();
        adapter.Fill(ds);
        Conn.Close();
        return ds.Tables[0];
    }
    catch (OleDbException e)
    {
        MessageBox.Show(e.Message + "\nWith error" + e.ErrorCode, "Error de base de datos");
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message, "Error general");
    }
    finally
    {
        Conn.Close(); //Just to be sure
    }
    return null;
}

正如我之前提到的,这在阅读文本和数字时效果很好(即使是我在其中存储大文本的备忘录字段),但它不适用于备忘录字段中的这个特定图像。

请注意,我确信数据库或字段都没有损坏。

默认情况下,OleDb 会将备注字段视为字符串。然而,在 C# 中,与文档不同的是,字符串是 ASCIIZ 字符串。它不会读过去看到一个 \x00 字符。您可以将该字段转换为 blob,从而读取为二进制值。这是一个例子:

用于创建示例数据的 VFP 代码:

CREATE TABLE c:\temp\imageData FREE (id i, ext c(3), filedata m)
INSERT INTO c:\temp\imageData (id, ext, filedata) VALUES (1,'jpg',FILETOSTR('C:\Program Files (x86)\Windows Kits\bin.0.17763.0\arm64\AccChecker\AccChecker_HelpFiles\image001.jpg'))
INSERT INTO c:\temp\imageData (id, ext, filedata) VALUES (2,'jpg',FILETOSTR('C:\Program Files (x86)\Windows Kits\bin.0.17763.0\arm64\AccChecker\AccChecker_HelpFiles\image002.jpg'))
INSERT INTO c:\temp\imageData (id, ext, filedata) VALUES (3,'jpg',FILETOSTR('C:\Program Files (x86)\Windows Kits\bin.0.17763.0\arm64\AccChecker\AccChecker_HelpFiles\image003.jpg'))

要从 VFP 读取的代码:

void Main()
{
    var table = SendQuery("select id, ext, cast(filedata as blob) as filedata from imageData");

    foreach (DataRow row in table.Rows)
    {
        var bytes = (byte[])row["filedata"];
        var id = (int)row["id"];
        var ext = (string)row["ext"];

        File.WriteAllBytes(Path.Combine(@"c:\temp", $"test_image{id}.{ext.Trim()}"),bytes);
    }
}

public DataTable SendQuery(string query)
{
    string cnStr = @"Provider=vfpoledb;Data Source=C:\Temp;";
    try
    {
        DataTable tbl = new DataTable();
        new OleDbDataAdapter(query, cnStr).Fill(tbl);
        return tbl;
    }
    catch (OleDbException e)
    {
        MessageBox.Show(e.Message + "\nWith error" + e.ErrorCode, "Error de base de datos");
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message, "Error general");
    }
    return null;
}

PS:您可以使用 Linq,因此您不会遇到这样的问题(Tom Brothers 有 VFP 的驱动程序 - Linq To VFP)。