2012-04-03 6 views
2

Ich greife auf eine Ms Access Datenbank durch C#. Ich kann alle Felder lesen. Das Problem, das ich bekomme, ist, während das Lesen .txt und .doc Dateien, die in OLE Object Feld der Tabelle gespeichert sind, eine Menge von zusätzlichen Junk-Zeichen werden auch vor und nach dem eigentlichen Text gelesen wie- ÿÿÿÿ‡€ ÿÿÿÿÿÿÿÿˆ ÿÿÿÿÿÿÿÿ€ ˆˆˆˆˆˆˆˆ€ ÿÿÿÿÿÿÿÿþ
i 8 @ñÿ 8 N o r m a l CJ _H aJ mH sH tH < [email protected]òÿ¡ <
D e f a u l t P a r a g r a p h F o n t … ÿÿÿÿ ( f p ³ ú ÿ A Ä M • À ' n ­ î 0 q Œ Ï
.Wie können Sie Junk-Zeichen entfernen, während Sie ein Word-Dokument lesen, das im Feld 'OLE-Objekt' in einer Zugriffsdatenbank über C# gespeichert ist?

Mein C# -Code ist wie- `

/*Read from the query and write in a temporary file*/ 
var oleBytes = (Byte[])Cmd.ExecuteScalar(); 
MemoryStream ms = new MemoryStream(); 
ms.Write(oleBytes, 0, oleBytes.Length - 0); 
var file = Path.GetTempFileName(); 
using (var fileStream = File.OpenWrite(file)) 
{ 
    var buffer = ms.GetBuffer(); 
    fileStream.Write(buffer, 0, (int)ms.Length); 
} 

`

Dann wie ein Wort document- `

Microsoft.Office.Interop.Word.ApplicationClass wordObject = new ApplicationClass(); 
object fpath = file; //this is the path 
object nullobject = System.Reflection.Missing.Value; 
Microsoft.Office.Interop.Word.Document docs = wordObject.Documents.Open 
(ref fpath, ref nullobject, ref nullobject, ref nullobject, 
ref nullobject, ref nullobject, ref nullobject, ref nullobject, 
ref nullobject, ref nullobject, ref nullobject, ref nullobject, 
ref nullobject, ref nullobject, ref nullobject, ref nullobject); 

docs.ActiveWindow.Selection.WholeStory(); 

docs.ActiveWindow.Selection.Copy(); 

IDataObject iData = Clipboard.GetDataObject(); 

if (iData != null) 
    data = iData.GetData(DataFormats.Text).ToString(); 

`

Don diese temporäre Datei lesen‘ Weißt du, was schief läuft? Liest ich die Felder Metadaten auch aus der Tabelle? Wenn ja, wie vermeide ich das? Was wäre der effiziente Weg zum Lesen OLE Object Feld, das andere Dateien als Bilder speichert?

+1

Das OLE-Objekt in Access enthält einen problematischen Wrapper, wie Sie bemerkt haben. Sie können http://stackoverflow.com/questions/2874403/strip-ole-header-information-ms-access-sql-server hilfreich finden. – Fionnuala

Antwort

3

Ich fand die Lösung für Word-Dokumente (.doc Dateien). Der OLE-Objektspeicher in Ms Access enthält einige Header-Informationen vor den eigentlichen Daten. Daher ist es einfach nicht möglich, den Feldinhalt als Byte-Array zu extrahieren und auf der Festplatte zu speichern. Jede OLE-Objektdatei hat eine Standardsignatur. Für Word-Dokumente, OLEheaderLength is 85 bytes. So Streifen I 85 Bytes von beiden Enden des Byte-Arrays wie-

Con.Open(); 
string _query="select licenseDoc from Products where ID=56"; 
//Column licenseDoc contains word and text douments as OLE Objects 
OleDbCommand Cmd = new OleDbCommand(_query, Con); 

const int offset =85; 
var oleBytes = (Byte[])Cmd.ExecuteScalar(); 
MemoryStream ms = new MemoryStream(); 
ms.Write(oleBytes, offset, oleBytes.Length - offset); 

var file = Path.GetTempFileName(); 
using (var fileStream = File.OpenWrite(file)) 
{ 
    var buffer = ms.GetBuffer(); 
    fileStream.Write(buffer, 0, (int)ms.Length); 
} 

Die Variable file wird den Pfad der .tmp Datei enthalten, die die Daten von der Word-Dokument als OLE object in Ms Access gespeichert gelesen enthält. Diese Datei kann direkt als word document geöffnet werden oder die Erweiterung kann geändert werden .doc.

Die OLEheaderLength für andere Formate sind wie folgt:

1] JPEG/JPG=224 
2] BMP=78 
3] PDF=85 
4] SNP=74 
5] DOC=85/90 
6] DOCX=87 

ich weiß nicht, die OLEheaderLength von .txt(Simple Text) files. Leider funktioniert die obige Lösung nur für .doc Dateien. Aber wenn es um .docx Dateien und andere Dateiformate geht, schlägt es fehl.

Um die Länge eines ole-Header, um herauszufinden, können Sie einfach die Bibliothek verwenden, die erklärt und Herunterladen von hier - http://jvdveen.blogspot.in/2009/02/ole-and-accessing-files-embedded-in.html

0

Ich habe versucht ein DOCX (.docx) & PDF-Dateien in Notepad++ öffnen und fand seltsam, aber Standard BOF(Beginning Of File) & EOF(End Of File) Zeichenfolge Muster. Dann fand ich eine Lösung zum Extrahieren von DOCX-Dateien (.docx) aus Ms Access DB. Für .docx Dateien ist OLEheaderLength 87 Bytes.

Con.Open(); 
string _query="select licenseDoc from Products where ID=56"; 
//Column licenseDoc contains word douments as OLE Objects 
OleDbCommand Cmd = new OleDbCommand(_query, Con); 

var oleBytes = (Byte[])Cmd.ExecuteScalar(); 

const string START_BLOCK = "PK";//DOCX files starts with "PK" 
const string END_BLOCK = "PK";//DOCX files ends with "PK" followed by some fixed 20 blank chars 
int startPos = -1; 
int endpos = -1; 

Encoding ascii = Encoding.ASCII; 
string strEncoding = ascii.GetString(oleBytes); 
if (strEncoding.IndexOf(START_BLOCK) != -1 && strEncoding.LastIndexOf(END_BLOCK) != -1) 
{ 
    startPos = strEncoding.IndexOf(START_BLOCK); 
    endpos = strEncoding.LastIndexOf(END_BLOCK) + END_BLOCK.Length + 20; 
} 
if (startPos == -1) 
{ 
    throw new Exception("Could not find DOCX Header"); 
} 

byte[] retByte = new byte[endpos - startPos]; 

Array.Copy(oleBytes , startPos, retByte, 0, endpos - startPos); 

MemoryStream ms = new MemoryStream(); 
ms.Write(retByte, 0, retByte.Length); 

var file = Path.GetTempFileName(); 
using (var fileStream = File.OpenWrite(file)) 
{ 
    var buffer = ms.GetBuffer(); 
    fileStream.Write(buffer, 0, (int)ms.Length); 
} 

Die Variablen file wird den Pfad der .tmp Datei enthält, die die Daten von dem Word-Dokument gespeichert als OLE-Objekt in MS Access lesen enthält.Diese Datei kann direkt als Word-Dokument geöffnet werden oder die Erweiterung kann in .docx geändert werden.

Bei PDF-Dateien gefunden, dass OLEheaderLength 85 OR 90. ich dies für PDF nicht versucht haben, aber Sie können using-

const string START_BLOCK = "%PDF";//PDF files starts with "%PDF" 
const string END_BLOCK = "%EOF";//PDF files ends with "%EOF" followed by some fixed 20 blank chars 

Um versuchen, die Länge eines ole, um herauszufinden, header, Sie könnten einfach die Bibliothek verwenden, die hier erklärt und herunterladbar ist - http://jvdveen.blogspot.in/2009/02/ole-and-accessing-files-embedded-in.html