gpt4 book ai didi

.net - 从 Access 数据库的附件字段中提取文件

转载 作者:太空狗 更新时间:2023-10-30 01:48:46 24 4
gpt4 key购买 nike

我们正在进行一个项目,我们需要将存储在 Access 数据库中的数据迁移到缓存数据库。 Access 数据库包含数据类型为 Attachment 的列;一些元组包含多个附件。我可以使用 .FileName 获取这些文件的文件名,但我不确定如何确定一个文件何时结束以及另一个文件何时开始 .FileData

我正在使用以下方法获取此数据:

System.Data.OleDb.OleDbCommand command= new System.Data.OleDb.OleDbCommand();
command.CommandText = "select [Sheet1].[pdf].FileData,* from [Sheet1]";
command.Connection = conn;
System.Data.OleDb.OleDbDataReader rdr = command.ExecuteReader();

最佳答案

(我对这个问题的原始回答具有误导性。对于随后使用 Adob​​e Reader 打开的 PDF 文件,它工作正常,但对于其他类型的文件,它并不总是能正常工作。以下是更正后的版本。 )

不幸的是,我们无法使用 OleDb 在 Access Attachment 字段中直接检索文件的内容。 Access 数据库引擎将一些元数据添加到文件的二进制内容中,如果我们通过 OleDb 检索 .FileData,则包含该元数据。

为了说明,使用 Access UI 将名为“Document1.pdf”的文档保存到附件字段。该 PDF 文件的开头如下所示:

Original.png

如果我们使用以下代码尝试将 PDF 文件提取到磁盘

using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = con;
cmd.CommandText =
"SELECT Attachments.FileData " +
"FROM AttachTest " +
"WHERE Attachments.FileName='Document1.pdf'";
using (OleDbDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
byte[] fileData = (byte[])rdr[0];
using (var fs = new FileStream(
@"C:\Users\Gord\Desktop\FromFileData.pdf",
FileMode.Create, FileAccess.Write))
{
fs.Write(fileData, 0, fileData.Length);
fs.Close();
}
}
}

然后生成的文件将在文件的开头包含元数据(在本例中为 20 个字节)

FromFileData.png

Adobe Reader 能够打开此文件,因为它足够强大,可以忽略文件中可能出现在“%PDF-1.4”签名之前的任何“垃圾”。不幸的是,并非所有文件格式和应用程序都对文件开头的无关字节如此宽容。

从 Access 中的 Attachment 字段中提取文件的唯一 Official™ 方法是使用 ACE DAO 的 .SaveToFile 方法 Field2 对象,像这样:

// required COM reference: Microsoft Office 14.0 Access Database Engine Object Library
//
// using Microsoft.Office.Interop.Access.Dao; ...
var dbe = new DBEngine();
Database db = dbe.OpenDatabase(@"C:\Users\Public\Database1.accdb");
Recordset rstMain = db.OpenRecordset(
"SELECT Attachments FROM AttachTest WHERE ID=1",
RecordsetTypeEnum.dbOpenSnapshot);
Recordset2 rstAttach = rstMain.Fields["Attachments"].Value;
while ((!"Document1.pdf".Equals(rstAttach.Fields["FileName"].Value)) && (!rstAttach.EOF))
{
rstAttach.MoveNext();
}
if (rstAttach.EOF)
{
Console.WriteLine("Not found.");
}
else
{
Field2 fld = (Field2)rstAttach.Fields["FileData"];
fld.SaveToFile(@"C:\Users\Gord\Desktop\FromSaveToFile.pdf");
}
db.Close();

请注意,如果您尝试使用 Field2 对象的 .Value,您仍然会在字节序列的开头获得元数据; .SaveToFile 过程将其剥离。

关于.net - 从 Access 数据库的附件字段中提取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25864092/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com