este problema se puede solucionar de variadas formas, pero nosotros te damos la que para nosotros es la resolución más completa.
Solución:
(Mi respuesta original a esta pregunta fue engañosa. Funcionó bien para los archivos PDF que se abrieron posteriormente con Adobe Reader, pero no siempre funcionó correctamente para otros tipos de archivos. La siguiente es la versión corregida).
Desafortunadamente, no podemos recuperar directamente el contenido de un archivo en un acceso Attachment
campo utilizando OleDb. El motor de base de datos de Access antepone algunos metadatos al contenido binario del archivo, y esos metadatos se incluyen si recuperamos el .FileData
a través de OleDb.
Para ilustrar, un documento llamado “Documento1.pdf” se guarda en un campo de archivo adjunto mediante la interfaz de usuario de Access. El comienzo de ese archivo PDF se ve así:
Si usamos el siguiente código para intentar extraer el archivo PDF al disco
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:UsersGordDesktopFromFileData.pdf",
FileMode.Create, FileAccess.Write))
fs.Write(fileData, 0, fileData.Length);
fs.Close();
entonces el archivo resultante incluirá los metadatos al principio del archivo (20 bytes en este caso)
Adobe Reader puede abrir este archivo porque es lo suficientemente robusto como para ignorar cualquier “basura” que pueda aparecer en el archivo antes de la firma ‘%PDF-1.4’. Desafortunadamente, no todos los formatos de archivo y aplicaciones perdonan tanto los bytes extraños al principio del archivo.
los solamente Forma oficial™ de extraer archivos de un Attachment
en Access es usar el .SaveToFile
método de un ACE DAO Field2
objeto, así:
// 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:UsersPublicDatabase1.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:UsersGordDesktopFromSaveToFile.pdf");
db.Close();
Tenga en cuenta que si intenta utilizar el .Value
del objeto Field2 aún obtendrá los metadatos al comienzo de la secuencia de bytes; la .SaveToFile
el proceso es lo que lo elimina.
Puntuaciones y comentarios
Nos puedes añadir valor a nuestra información colaborando tu experiencia en las ilustraciones.