- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
对于 C# 网络应用程序,我想从存储在数据库中的 PDF、DOC 等文件中索引文本。
我一直在试验 an IFilter example on Code Project这对文件系统中的文件非常有效,但我的文件存储在 MS-SQL 数据库中。
任何人都可以帮我找到一个示例以从存储在数据库中的文件中提取文本,或者知道如何修改代码项目代码以使用数据库而不是文件系统吗?
最佳答案
终于在几个小时后我想出了如何使这个工作!我需要对存储在数据库中的 PDF 内容运行 IFilter,并且我想避免将数据保存到临时文件中。
首先我尝试使用 BindIFilterFromStream为存储在 Stream 中的内容创建 IFilter 的 API,但它似乎不能正常工作(至少在这种情况下不能)。所以不要走那条路。
相反,您需要为文件扩展名创建一个 IFilter(或以其他方式访问它)。然后你可以访问 IPersistStream COM 接口(interface)并使用它将 PDF 内容加载到 IFilter 中。其余工作与文件相同。但是,请注意 IPersistStream API 可能并非由每个 IFilter 实现。不过它适用于 Adobe PDF IFilter。
代码应如下所示(我删除了一些返回码检查以使代码更具可读性,但是,您应该检查所有可能的返回码)。
private string ParseIFilter(Stream s)
{
// Get an IFilter for a file or file extension
IFilter filter = null;
FilterReturnCodes result = NativeMethods.LoadIFilter(".pdf", null, ref filter);
if (result != FilterReturnCodes.S_OK)
{
Marshal.ThrowExceptionForHR((int)result);
}
// Copy the content to global memory
byte[] buffer = new byte[s.Length];
s.Read(buffer, 0, buffer.Length);
IntPtr nativePtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, nativePtr, buffer.Length);
// Create a COM stream
System.Runtime.InteropServices.ComTypes.IStream comStream;
NativeMethods.CreateStreamOnHGlobal(nativePtr, true, out comStream);
// Load the contents to the iFilter using IPersistStream interface
var persistStream = (IPersistStream)filter;
persistStream.Load(comStream);
// Initialize iFilter
FilterFlags filterFlags;
FilterReturnCodes result = filter.Init(
FilterInit.IFILTER_INIT_INDEXING_ONLY, 0, IntPtr.Zero, out filterFlags);
return ExtractTextFromIFilter(filter);
}
从过滤器中提取的文本在我的代码中看起来像这样。网络上有很多这方面的示例,可以根据您的需要以多种方式实现。
private string ExtractTextFromIFilter(IFilter filter)
{
var sb = new StringBuilder();
while (true)
{
StatChunk chunk;
result = filter.GetChunk(out chunk);
if (result == FilterReturnCodes.S_OK)
{
if (chunk.flags == ChunkState.CHUNK_TEXT)
{
sb.Append(ExtractTextFromChunk(filter, chunk));
}
continue;
}
if (result == FilterReturnCodes.FILTER_E_END_OF_CHUNKS)
{
return sb.ToString();
}
Marshal.ThrowExceptionForHR((int)result);
}
}
private virtual string ExtractTextFromChunk(IFilter filter, StatChunk chunk)
{
var sb = new StringBuilder();
var result = FilterReturnCodes.S_OK;
while (result == FilterReturnCodes.S_OK)
{
int sizeBuffer = 16384;
var buffer = new StringBuilder(sizeBuffer);
result = filter.GetText(ref sizeBuffer, buffer);
if ((result == FilterReturnCodes.S_OK) || (result == FilterReturnCodes.FILTER_S_LAST_TEXT))
{
if((sizeBuffer > 0) && (buffer.Length > 0))
{
sb.Append(buffer.ToString(0, sizeBuffer));
}
}
if (result == FilterReturnCodes.FILTER_E_NO_TEXT)
{
return string.Empty;
}
if ((result == FilterReturnCodes.FILTER_S_LAST_TEXT) || (result == FilterReturnCodes.FILTER_E_NO_MORE_TEXT))
{
return sb.ToString();
}
}
return sb.ToString();
}
这里是本地方法的定义和它们使用的结构。
internal static class NativeMethods
{
[DllImport("query.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern FilterReturnCodes LoadIFilter(
string pwcsPath,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
ref IFilter ppIUnk);
[DllImport("ole32.dll")]
public static extern int CreateStreamOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, out IStream ppstm);
}
[ComImport, Guid("89BCB740-6119-101A-BCB7-00DD010655AF")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFilter
{
[PreserveSig]
FilterReturnCodes Init(FilterInit grfFlags, int cAttributes, IntPtr aAttributes, out FilterFlags pdwFlags);
[PreserveSig]
FilterReturnCodes GetChunk(out StatChunk pStat);
[PreserveSig]
FilterReturnCodes GetText(
ref int pcwcBuffer,
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder awcBuffer);
[PreserveSig]
FilterReturnCodes GetValue(ref IntPtr propVal);
[PreserveSig]
FilterReturnCodes BindRegion(ref FilterRegion origPos, ref Guid riid, ref object ppunk);
}
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000010c-0000-0000-C000-000000000046")]
public interface IPersist
{
void GetClassID(out Guid pClassID);
}
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000109-0000-0000-C000-000000000046")]
public interface IPersistStream : IPersist
{
new void GetClassID(out Guid pClassID);
[PreserveSig]
int IsDirty();
void Load([In] IStream pStm);
void Save(
[In] IStream pStm,
[In, MarshalAs(UnmanagedType.Bool)] bool fClearDirty);
void GetSizeMax(out long pcbSize);
}
public struct StatChunk
{
public int idChunk;
[MarshalAs(UnmanagedType.U4)]
public ChunkBreaktype breakType;
[MarshalAs(UnmanagedType.U4)]
public ChunkState flags;
public int locale;
public FullPropSpec attribute;
public int idChunkSource;
public int cwcStartSource;
public int cwcLenSource;
}
public enum ChunkBreaktype
{
CHUNK_NO_BREAK = 0,
CHUNK_EOW = 1,
CHUNK_EOS = 2,
CHUNK_EOP = 3,
CHUNK_EOC = 4
}
public enum ChunkState
{
CHUNK_TEXT = 0x1,
CHUNK_VALUE = 0x2,
CHUNK_FILTER_OWNED_VALUE = 0x4
}
[Flags]
public enum FilterFlags
{
IFILTER_FLAGS_OLE_PROPERTIES = 1
}
[Flags]
public enum FilterInit
{
IFILTER_INIT_CANON_PARAGRAPHS = 1,
IFILTER_INIT_HARD_LINE_BREAKS = 2,
IFILTER_INIT_CANON_HYPHENS = 4,
IFILTER_INIT_CANON_SPACES = 8,
IFILTER_INIT_APPLY_INDEX_ATTRIBUTES = 16,
IFILTER_INIT_APPLY_CRAWL_ATTRIBUTES = 256,
IFILTER_INIT_APPLY_OTHER_ATTRIBUTES = 32,
IFILTER_INIT_INDEXING_ONLY = 64,
IFILTER_INIT_SEARCH_LINKS = 128,
IFILTER_INIT_FILTER_OWNED_VALUE_OK = 512
}
public struct FilterRegion
{
public int idChunk;
public int cwcStart;
public int cwcExtent;
}
public enum FilterReturnCodes : uint
{
S_OK = 0,
E_ACCESSDENIED = 0x80070005,
E_HANDLE = 0x80070006,
E_INVALIDARG = 0x80070057,
E_OUTOFMEMORY = 0x8007000E,
E_NOTIMPL = 0x80004001,
E_FAIL = 0x80000008,
FILTER_E_PASSWORD = 0x8004170B,
FILTER_E_UNKNOWNFORMAT = 0x8004170C,
FILTER_E_NO_TEXT = 0x80041705,
FILTER_E_NO_VALUES = 0x80041706,
FILTER_E_END_OF_CHUNKS = 0x80041700,
FILTER_E_NO_MORE_TEXT = 0x80041701,
FILTER_E_NO_MORE_VALUES = 0x80041702,
FILTER_E_ACCESS = 0x80041703,
FILTER_W_MONIKER_CLIPPED = 0x00041704,
FILTER_E_EMBEDDING_UNAVAILABLE = 0x80041707,
FILTER_E_LINK_UNAVAILABLE = 0x80041708,
FILTER_S_LAST_TEXT = 0x00041709,
FILTER_S_LAST_VALUES = 0x0004170A
}
public struct FullPropSpec
{
public Guid guidPropSet;
public PropSpec psProperty;
}
[StructLayout(LayoutKind.Explicit)]
public struct PropSpec
{
[FieldOffset(0)]
public int ulKind;
[FieldOffset(4)]
public int propid;
[FieldOffset(4)]
public IntPtr lpwstr;
}
关于c# - 在 C# 中使用 IFilter 并从数据库而不是文件系统中检索文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7313828/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!