2022-05-21

JAVA文件搜索过程中如何得到各种文件内容(office文件,PDF,邮件,mht,思维导图等)


现在流行的搜索引擎Lucene, Elasticsearch处理文件搜索时一般使用 tika,使用tika 处理文件正文搜索还好,但搜索结果显示正文等操作不是很方便,并且tika提取正文的速度比较慢。老版本还有很多外部依赖程序,安全性不好。

笔者给大家介绍一款调用方便,提取文件正文速度快,开发方便的组件供大家参考。

“Graccvs正文提取组件”全部用go语言实现,不依赖外部工具,效率高,安全性非常好。可以直接在操作系统上开发使用,不要求JAVA等其他环境支持,而且从设计上避免了环境依赖或者解析器框架带来的占用CPU过高和安全性问题。组件提取文本速度快,质量高,跨平台,支持多任务并发,开发简单成本低。提供多种语言接口及使用示例。

“Graccvs正文提取组件”支持很多文件格式:

A: pdf文件

B: office word文件 ".doc", ".odt", ".docx", ".dotm", ".docm"

C: wps文档 ".wps"

D: office excel文件 ".xls", ".xlsx", ".xlsm", ".xltm"

E: wps表格 ".et"

F: office powerPoint文件 ".ppt", ".pptx", ".potm", ".pptm", ".ppsm"

G: wps演示 ".dps"

H:开放文档格式 ".ofd", 注:常见于“电子发票版式文件”

I:富文本类型 ".rtf"

J: HTML页面文件  ".html", ".htm", ".mht", ".mhtml"

K:邮件格式文件 ".eml", 注:默认提取前5个附件

L:部分思维导图格式文件 ".emmx", "xmind", "gmind"

M: UTF8编码, Unicode编码, Ansi编码的文本文件,

           ".txt", ".c", ".h", ".cpp", ".m", ".asp", ".aspx", ".cs", ".pas",

          ".php", ".vb", ".bas", ".js", ".css", ".java", ".jsp", ".go",

           ".pl", ".perl", ".ps", ".py", ".python", ".sql", ".rs", ".dart"

注:可以在配置文件中增加纯文本文件后缀

N:帮助文件 “*.chm",注:此格式仅限Windows平台

O:压缩文件 ".zip", 注:默认提取前5个文件

以下是使用Eclipse开发工具,Java调用动态链接库示例:

调用过程:1:创建JAVA工程。2:工程导入调用DLL的扩展包Native(jna-jpms-5.9.0.jar 和 jna-platform-jpms-5.9.0.jar)。3:拷贝 graccvs64.dll到工程中,LibGraccvs.java单元修改DLL位置(默认在exe输出位置)。4:实现提取文件正文函数,点击这里查看DLL函数详细说明。5:点击这里下载完整工程包,这里下载最新DLL文件

主要代码单元LibGraccvs.java (函数的定义):

package graccvsDLL;

//

import com.sun.jna.Library;

import com.sun.jna.Native;

import com.sun.jna.Pointer;

//

public interface LibGraccvs extends Library {

//默认64位系统,32位DLL或者接口最新DLL查看官网

@SuppressWarnings("deprecation")

LibGraccvs INSTANCE = (LibGraccvs) Native.loadLibrary("graccvs64.dll", LibGraccvs.class);


//----------------------以下为函数说明----------------------

// 加载DLL,设置动态库需要的临时文件夹,且对此文件夹要有读写权限

void Load(Pointer tempDir);


//注册软件:

int Auth(Pointer corp, Pointer licText);


// 提供文件正文,并保存到目标文件

// inFilePtr输入文件地址, outFilePtr为TXT目标文件文件地址

int ToTextFile(Pointer inFilePtr, Pointer outFilePtr);


//其他一个文件的正文,返回UTF-8字符串指针

//注意,调用此函数需要使用FreeString释放指针内存

Pointer ToString(Pointer inFilePtr);


//得到最后错误日志

Pointer LastErr();


//释放ToString函数返回的指针内存

void FreeString(Pointer ptr);


// 提取Http/Https文件,返回字符串数据指针

// url=Http/Https地址

// fileExt=文件类型(比如:".pdf"),

// timeout=超时设置,超过此数值系统终止下载文件。单位为毫秒,默认为0(等待文件下载直到完成)

// httpParams=JSON格式header数据和cookie数据,默认为空

// 返回UTF-8编码字符串数据指针(此指针需要使用FreeString函数释放内存)

Pointer HttpToString(Pointer url, Pointer fileExt, int timeout, Pointer httpParams);


// 下载Http文件,并提取文本,保存到目标文件u

// outfile为TXT目标文件文件地址,其他参数和HTTPTOSTRING参数相同

int HttpToTextFile(Pointer url, Pointer fileExt, Pointer outfile, int timeout, Pointer httpParams);


//---------------------异步批量处理相关函数---------------------

// 文件提取异步任务, inFilePtr输入文件地址, outTxtFilePtr为TXT目标文件文件

// 如果提取某个文件错误,则 结果文本的内容如下格式: @ErrCode:错误代码, ErrMessage:错误提示

void AddTask(Pointer inFilePtr, Pointer outTxtFilePtr);


// 异步提取Http文件任务,参数同 HttpToTextFile 函数

void AddHttpTask(Pointer url, Pointer fileExt, Pointer outTxtFile, int timeout, Pointer httpParams);


// 开始执行异步任务,返回值=1开始执行, 其他值未识别

// =2 免费版不支持此功能,=3 没有可以执行的任务 ,=4 当前任务未完成

int AsyncStart();


// 停止任务

void AsyncStop();


// 一直等待,直到全部异步任务结束

void AsyncWait();


// 得到执行异步任务的状态, =0 没开始, =1 正在处理中,=2 已中断, =99 处理完成

int AsyncState();


// 设置执行异步任务的并发数量(不大于软件授权数量),返回并发数量

int AsyncMaxProcs(int num);

//---------------------异步批量处理相关函数---------------------


//程序结束前调用此函数,否则释放DLL会发生错误

void Unload();

}


主要代码单元TestMain.java (提取文件正文测试):


package graccvsDLL;

//

import java.io.UnsupportedEncodingException;

import java.util.*;

import com.sun.jna.Memory;

import com.sun.jna.Pointer;


//

public class TestMain {


public enum DllErrCode

{

TFE_OK,

TFE_UNKNOW,

TFE_FILE_NOTEXIST,

TFE_SAVE_ERROR,

TFE_OUTSIZE,

TFE_UNSUPPORTED ,

TFE_ERROR_INTERFACE ,

TFE_HTTP_ERR,

TFE_HTTP_FILE_NULL ,

TFE_LICENCE_ERR;

}


// 根据错误类型返回错误信息

public static String codeText(DllErrCode code)

{

switch (code)

{

case TFE_OK:

return "ok";

case TFE_UNKNOW:

return "未知错误";

case TFE_FILE_NOTEXIST:

return "提取源文件不存在";

case TFE_SAVE_ERROR:

return "保存目标文件失败";

case TFE_OUTSIZE:

return "提取的源文件超出设置的大小范围";

case TFE_UNSUPPORTED:

return "不支持的提取文件格式";

case TFE_ERROR_INTERFACE:

return "得到接口失败";

case TFE_HTTP_ERR :

return "HTTP下载文件失败";

case TFE_HTTP_FILE_NULL :

return "HTTP文件为空";

case TFE_LICENCE_ERR:

return "软件许可错误";

default:

return "未知错误2";

}

}


//字符串转指针

public static Pointer getUtf8Pointer(String str){  

try {

byte[] data = str.getBytes("UTF-8");

Pointer p = new Memory(data.length + 1);

p.write(0, data, 0, data.length);

p.setByte(data.length, (byte)0);

return p;

}catch (UnsupportedEncodingException e) {

return null;

}

}


//utf8指针转换为字符串

public static String utf8pointerToString(Pointer p){  

String str = p.getString(0);

try {

return new String(str.getBytes(), "UTF-8");  

}catch (UnsupportedEncodingException e){

return str;

}

}


// ------------------------提取正文并保存为文本文件------------------------

public static void testToTextFile(){  

Pointer prtInFile = getUtf8Pointer("test\\graccvs文件正文提取接口.pdf");

Pointer prtOutFile = getUtf8Pointer("test\\grcv001.txt");   


//

int r = LibGraccvs.INSTANCE.ToTextFile(prtInFile, prtOutFile);  

DllErrCode code = DllErrCode.values()[r];  

if (code != DllErrCode.TFE_OK)

{

// 得到错误方式1: 根据R值调用函数ErrText得到具体错误信息, 此方式速度快

String err = codeText(code);

System.out.println("error from code:" + err);


// 方式2:调用DLL函数,得到具体错误信息, 此方式错误信息更加准确

Pointer p = LibGraccvs.INSTANCE.LastErr();

String err2 = utf8pointerToString(p);

System.out.println("error from dll lastErr:" + err2);

}


System.out.println("to text ok!");

}


// ------------------------提取正文,返回字符串指针------------------------

public static void testToString(){  

Pointer prtInFile = getUtf8Pointer("test\\简可信模板OCR识别工具帮助.docx");   

Pointer prtOutStr = LibGraccvs.INSTANCE.ToString(prtInFile);

try

{

String s = utf8pointerToString(prtOutStr);

System.out.println(s);

}

finally

{

LibGraccvs.INSTANCE.FreeString(prtOutStr); //调用此函数释放字符串内存,否则会导致内存泄漏

}

}


// ------------------------HTTP提取正文并保存为文本文件------------------------

public static void testHttpToTextFile()

{  

Pointer prtUrl = getUtf8Pointer("https://www.gaya-soft.cn/dfs/v2/简可信模板OCR识别工具帮助.docx");

Pointer prtExt = getUtf8Pointer(".docx");

Pointer prtOutFile = getUtf8Pointer("test\\grcv002.txt");

// 调用DLL函数得到文件正文

int r = LibGraccvs.INSTANCE.HttpToTextFile(prtUrl, prtExt, prtOutFile, 0, null);

DllErrCode code = DllErrCode.values()[r];

//TFE_OK为提取完成,其他code调用codeText返回相同错误

if (code != DllErrCode.TFE_OK)

{  

System.out.println("error from code, " + codeText(code));

}

else

{

System.out.println("testHttpToTextFile end");

}

}


// ------------------------HTTP提取正文,返回字符串指针------------------------

public static void testHttpToString()

{

Pointer prtUrl = getUtf8Pointer("https://www.gaya-soft.cn/dfs/v2/graccvs文件正文提取接口.pdf");

Pointer prtExt = getUtf8Pointer(".pdf");

String  params = "{\"headers\":[{\"client_id\": \"g01x9\"}, {\"client_secret\": \"e23c89cc9fe\"}], \"cookies\":[{\"name\": \"ga\", \"value\": \"1020\", \"expires\":36000000, \"path\": \"/\"}]}";

Pointer prtParams = getUtf8Pointer(params);

int timeout = 60 * 1000; //超时设置,单位毫秒, 默认为0

//

Pointer prtOutStr = LibGraccvs.INSTANCE.HttpToString(prtUrl, prtExt, timeout, prtParams);

try

{

String s = utf8pointerToString(prtOutStr);

System.out.println(s);

}

finally

{

LibGraccvs.INSTANCE.FreeString(prtOutStr); // 务必调用函数释放字符串内存

}

}


// ---------------异步批量文件提取,适合多线程处理很多文件---------------

// 文件提取任务

public static void asyncAddTask()

{   

// -----可以增加N个任务    

Pointer prtInFile = getUtf8Pointer("test\\graccvs文件正文提取接口.pdf");

Pointer prtOutFile = getUtf8Pointer("test\\asyncOut001.txt");

LibGraccvs.INSTANCE.AddTask(prtInFile, prtOutFile); // 一个文件任务


Pointer prtInFile2 = getUtf8Pointer("test\\Adobe Intro.ofd");

Pointer prtOutFile2 = getUtf8Pointer("test\\asyncOut002.txt");

LibGraccvs.INSTANCE.AddTask(prtInFile2, prtOutFile2); // 一个文件任务

}


// Http文件提取任务

public static void asyncAddHttpTask()

{

// 可以增加N个任务

Pointer prtUrl = getUtf8Pointer("https://www.gaya-soft.cn/dfs/v2/简可信模板OCR识别工具帮助.docx");

Pointer prtExt = getUtf8Pointer(".docx");

Pointer prtOutFile = getUtf8Pointer("test\\asyncOut003.txt");  

int timeout = 90 * 1000; //超时设置,单位毫秒, 默认为0

LibGraccvs.INSTANCE.AddHttpTask(prtUrl, prtExt, prtOutFile, timeout, null);

}


// 方式1:开始任务,等待全部任务完成

public static void asyncRun1()

{  

// 开始任务

int r = LibGraccvs.INSTANCE.AsyncStart();

if (r == 1){  

LibGraccvs.INSTANCE.AsyncWait(); // 等待任务全部结束

System.out.println("方式1 -- 任务完成");

}else if (r == 2){

System.out.println("免费版不支持此功能");

}else if (r == 3){

System.out.println("没有可以执行的任务");

}else if (r == 4){

System.out.println("当前任务未完成");

}

}


// 方式2:判断执行情况,超时退出,主动结束任务

public static void asyncRun2()  

{

// 开始任务

boolean isOver = false;

int r = LibGraccvs.INSTANCE.AsyncStart();

if (r == 1){

Date startDt = new Date();

// 5分钟后结束任务

while((new Date()).getTime() - startDt.getTime() < 5 * 60 * 1000){

// 判断任务情况, =0 没开始, =1 正在处理中,=2 已中断, =99 处理完成

int x = LibGraccvs.INSTANCE.AsyncState();

if (x == 1){

try

{

Thread.sleep(500);

}

catch(InterruptedException e)

{

}

}else if (x == 99){

isOver = true; // 处理完成

break;

}else{

break;

}

}

//

if (!isOver){

LibGraccvs.INSTANCE.AsyncStop(); // 结束任务

}   

System.out.println("方式2 -- 任务完成");

}else if (r == 2){

System.out.println("免费版不支持此功能");

}else if (r == 3){

System.out.println("没有可以执行的任务");

}else if (r == 4){

System.out.println("当前任务未完成");

}

}


public static void asyncTest()

{

//

LibGraccvs.INSTANCE.AsyncMaxProcs(8); // 同时运行8个任务

//

asyncAddTask();     // 文件提取任务

asyncAddHttpTask(); // Http文件提取任务

// 执行任务--方式1

asyncRun1();


// 执行任务--方式2

asyncAddTask();

asyncAddHttpTask();

asyncRun2();

}

// ---------------异步批量文件提取,适合多线程处理很多文件---------------


public static void main(String[] args) {

Pointer prtPath = getUtf8Pointer("test");

// 提取文本需要的临时文件夹,且对此文件夹要有读写权限

LibGraccvs.INSTANCE.Load(prtPath);


// 设置软件许可,免费版都为空

Pointer corp = getUtf8Pointer("gaya-soft.cn");

Pointer licTxt = getUtf8Pointer("");

LibGraccvs.INSTANCE.Auth(corp, licTxt);



// 提取正文并保存为文本文件

testToTextFile(); //


// 提取正文,返回字符串指针

testToString();


// 提取HTTP提取正文, 并保存为文本文件

testHttpToTextFile();

// 提取HTTP提取正文, 返回字符串指针

testHttpToString();


// 异步批量文件提取测试

asyncTest();


//

LibGraccvs.INSTANCE.Unload();

//

String s2 = "over!";

System.out.println(s2);

}

}       

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容

  • C#文件搜索过程中如何提取office文件,wps,pdf,html,eml等格式的文件正文 本组件智能分析提取其...
    longemail阅读 243评论 0 0
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,221评论 11 349
  • Java 常见英语单词 (1.0 版本) 1. Java 基础常见英语词汇(70 个) OO: object-or...
    Nemo359阅读 2,167评论 0 0
  • Topics in this section include: 本节主题包括: What makes Java p...
    思考z阅读 280评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139