C# 从 Access .accdb 读取附件

C# read attachments from Access .accdb

我必须从 .accdb 文件中读取 table 并将其迁移到数据库。 我无法在将执行迁移的服务器上安装 MS Access! 目前我使用 ODBC

OdbcConnection DbConnection = new OdbcConnection("DSN=SAMPLE_ISAM");
DbConnection.Open();
OdbcCommand DbCommand = DbConnection.CreateCommand();
DbCommand.CommandText = "SELECT Attachments FROM SomeTable";
OdbcDataReader DbReader = DbCommand.ExecuteReader();
while (DbReader.Read())
{
    object att = DbReader["Attachments"];
}
DbReader.Close();
DbCommand.Dispose();
DbConnection.Close();

SAMPLE_ISAM指向accdb文件。 这适用于简单的数据类型,但对于附件,它只获取文件名(我还需要字节)。

正如我所说,无法安装 MS Access,因此 Interop DAO 不是一个选项。

有什么办法可以得到附件吗?其他技术和编程语言也是acceptable。

感谢史蒂夫,我找到了这个 Extracting files from an Attachment field in an Access database

所以工作代码是:

            OdbcConnection DbConnection = new OdbcConnection("DSN=SAMPLE_ISAM");
            DbConnection.Open();
            OdbcCommand DbCommand = DbConnection.CreateCommand();
            DbCommand.CommandText = "SELECT Attachments.FileData, ID, Attachments.FileName FROM Complaints WHERE ID IN(29,30)";
            OdbcDataReader DbReader = DbCommand.ExecuteReader();
            int fCount = DbReader.FieldCount;
            while (DbReader.Read())
            {
                byte[] bytes = (byte[])DbReader[0];
                Int32 ID = (Int32)DbReader[1];
                string name = (string)DbReader[2];
                File.WriteAllBytes(@"D:\files\" + name, bytes.Skip(20).ToArray());
            }
            DbReader.Close();
            DbCommand.Dispose();
            DbConnection.Close();

using System.Linq;Skip(20) 所必需的(参见 link)。 pdf 和 jpg 的元数据为 20 字节。请注意,它可能因其他文件类型而异。

我不确定 header 格式是什么,但第一个字节会告诉你 header 的长度,以扩展 evgeni 的示例:

        OdbcConnection DbConnection = new OdbcConnection("DSN=SAMPLE_ISAM");
        DbConnection.Open();
        OdbcCommand DbCommand = DbConnection.CreateCommand();
        DbCommand.CommandText = "SELECT Attachments.FileData, ID, Attachments.FileName FROM Complaints WHERE ID IN(29,30)";
        OdbcDataReader DbReader = DbCommand.ExecuteReader();
        int fCount = DbReader.FieldCount;
        while (DbReader.Read())
        {
            byte[] bytes = (byte[])DbReader[0];
            Int32 ID = (Int32)DbReader[1];
            string name = (string)DbReader[2];
            File.WriteAllBytes(@"D:\files\" + name, bytes.Skip((int)bytes[0]).ToArray());
        }
        DbReader.Close();
        DbCommand.Dispose();
        DbConnection.Close();

但我认为如果附件中有多个文件,这将不起作用...怀疑 header 也说明偏移量 5 处有多少附件,但需要更多测试看看是否是这种情况。