Как удалить ненужные символы при чтении текстового документа, хранящегося в поле «OLE Object» в базе данных доступа через C #? - PullRequest
2 голосов
/ 03 апреля 2012

Я обращаюсь к базе данных Ms Access через C#.Я могу прочитать все поля.Проблема, которую я получаю, заключается в том, что при чтении файлов .txt и .doc, которые хранятся в поле OLE Object таблицы, многие дополнительные ненужные символы также читаются до и после фактического текста, например - * 1006.*.

Мой код на C # похож на `` 1009 *

/*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);
 }

`

Затем прочитайте этот временный файл как слово 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();

`

Не знаете, что происходит?Читаю ли я метаданные полей также из таблицы?Если так, то как этого избежать?Какой эффективный способ прочитать поле OLE Object, в котором хранятся файлы, отличные от изображений?

Ответы [ 2 ]

3 голосов
/ 04 апреля 2012

Я нашел решение для текстовых документов (.doc файлов).Хранилище OLE-объектов в Ms Access содержит некоторую информацию заголовка перед фактическими данными, поэтому простое извлечение содержимого поля в виде байтового массива и сохранение его на диск не работает.Любой объектный файл OLE имеет стандартную подпись.Для текстовых документов OLEheaderLength is 85 bytes.Поэтому я удаляю 85 байтов с обоих концов массива байтов, например:

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);
}

. Переменная file будет содержать путь к файлу .tmp, который содержит данные, прочитанные из сохраненного документа Word.как OLE object in Ms Access.Этот файл может быть непосредственно открыт как word document или его расширение может быть изменено .doc.

OLEheaderLength для других форматов следующие:

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

Донне знаю OLEheaderLength из .txt(Simple Text) files.К сожалению, вышеприведенное решение работает только для файлов .doc.Но когда дело доходит до .docx файлов и любых других форматов файлов, происходит сбой.

Чтобы узнать длину заголовка ole, вы можете просто использовать библиотеку, которая поясняется и загружаетсяотсюда - http://jvdveen.blogspot.in/2009/02/ole-and-accessing-files-embedded-in.html

0 голосов
/ 26 июля 2012

Я попытался открыть файлы DOCX (.docx) & PDF в Notepad++ и обнаружил странные, но стандартные BOF(Beginning Of File) & EOF(End Of File) строковые шаблоны. Затем я нашел решение для извлечения файлов DOCX (.docx) из БД Ms Access. Для .docx файлов OLEheaderLength составляет 87 байт.

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);
}

Переменная file будет содержать путь к файлу .tmp, который содержит данные, прочитанные из документа word, хранящегося как объект OLE в Ms Access. Этот файл может быть непосредственно открыт как текстовый документ или его расширение может быть изменено на .docx.

Для файлов PDF обнаружено, что OLEheaderLength равно 85 ИЛИ 90. Я не пробовал это для PDF, но вы можете попробовать -

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

Чтобы узнать длину заголовка ole, вы можете просто использовать библиотеку, которая поясняется и загружается отсюда - http://jvdveen.blogspot.in/2009/02/ole-and-accessing-files-embedded-in.html

...