2022-05-20

C#文件搜索过程中如何提取office文件,wps,pdf,html,eml等格式的文件正文


本组件智能分析提取其他各种文件中文本,为自然语言信息检索,机器学习等高端技术提供底层支持的技术组件,是Lucene/CLucene, Elasticsearch, Sphinx等全文检索工具,OA, ERP, CRM,网盘,文件管理等其他系统提供文件摘要及搜索前置服务。同时也可以为安全网关,邮件内容监控,内网安全等系统提供文件搜索及监控服务底层技术支持。   

组件提供C#使用组件对大量文件进行文件内容的搜索,为Lucene.Net等提供底层技术支持。系统调用简单方便,效率高。

以下几个步骤即可:

1:解压直接打开graccvsTest工程

2:到官网下载graccvs64.dll保存到EXE执行程序所在文件夹下, DLL下载地址

3:代码中从64行开始定义函数, 从258行是文件取正文示例, testToTextFile函数可以直接输入文件名称函数提取正文并保存为文本文件,  testToString输入rft, html, pdf等文件名称放回字符串. 示例中还提供直接下载HTTP文件并提取正文的方法,使用超级简单.

4:免费版可以提取50%-80%的文本,基本够用了。

5:可以下载完整工程包直接测试,   工程下载地址

6:以下是代码

using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;using System.Threading;


namespace graccvsTest

{

    public class DllInvoke

    {   

        [DllImport("kernel32.dll")]

        private extern static IntPtr LoadLibrary(string path);


        [DllImport("kernel32.dll")]

        private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);


        [DllImport("kernel32.dll")]

        private extern static bool FreeLibrary(IntPtr lib);


        private IntPtr hLib;

        public DllInvoke(String DLLPath)

        {

            hLib = LoadLibrary(DLLPath);

        }


        ~DllInvoke()

        {

            if (hLib != null)

            {

                FreeLibrary(hLib);

            }

        }


        public Delegate Invoke(string APIName, Type t)

        {

            if (hLib != null)

            {

                IntPtr api = GetProcAddress(hLib, APIName);

                return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);

            }

            else

            {

                return null;

            }

        }

    }


    class Program

    {

        //--------------------------------函数定义--------------------------------

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

        public delegate void LOAD(IntPtr tempPathPtr);


        /*

注册软件:

方式1:输入参数,corp为公司名称licText为注册码

方式2:把授权文件grauth.lic保存到动态库相同文件夹,调用TAuth函数(corp, licText都为空)系统自动加载grauth.lic

返回值:

            0:免费版本许可为空

            1:许可正常

            2:序列号(公司授权名称)错误

            3:加密数据格式错误

            4:许可过期

            5:许可验证错误

            6:无效的许可

            7:未知错误


注1:如果注册失败,系统变为免费版本

注2:免费版也需要调用此函数,corp和licText都为空

        */

        public delegate Int32 AUTH(IntPtr corp, IntPtr licText);


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

        // inFilePtr输入文件指针, outFilePtr为TXT目标文件文件指针

        public delegate Int32 TOTEXTFILE(IntPtr inFilePtr, IntPtr outFilePtr);

        // 提供文件正文

        // inFilePtr输入文件指针, 返回UTF-8编码字符串数据指针(此指针需要使用FREESTRING函数释放内存)

        public delegate IntPtr TOSTRING(IntPtr inFilePtr);

        // 释放TOSTRING等函数的返回指针

        public delegate void FREESTRING(IntPtr p);

        // 得到最后的错误信息

        public delegate IntPtr LASTERR();


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

        // url=Http/Https地址

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

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

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

        /*   

          JSON格式如下:

          {"headers":

          [{名称1: 值1},{名称2: 值2},...],

          "cookies":[

          {"name": 名称(字符串), "value": 值(字符串), "expires": 有效期(整数,单位毫秒),

          "path": 路径(字符串), "domain": 域名(字符串)},

          {"name": 名称(字符串), "value": 值(字符串), "expires": 有效期(整数,单位毫秒),

          "path": 路径(字符串), "domain": 域名(字符串)}

          ...

          ]}

例如:

          {"headers":[{"client_id": "g01x9"}, {"client_secret": "e23c89cc9fe"}, {"client_index": 10092}],

          "cookies":[{"name": "ga", "value": "1020", "expires":36000000, "path": "/hx/", "domain":"www.gaya-soft.cn"},

          {"name": "xc3", "value": "10099", "expires":240000, "path": "", "domain":""}]}

        */

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

        public delegate IntPtr HTTPTOSTRING(IntPtr url, IntPtr fileExt, Int32 timeout, IntPtr httpParams);


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

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

        public delegate Int32 HTTPTOTEXTFILE(IntPtr url, IntPtr fileExt, IntPtr outfile, Int32 timeout, IntPtr httpParams);


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

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

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

        public delegate void ADDTASK(IntPtr inFilePtr, IntPtr outTxtFilePtr);

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

        public delegate void  ADDHTTPTASK(IntPtr url, IntPtr fileExt, IntPtr outTxtFile, Int32 timeout, IntPtr httpParams);  

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

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

        public delegate Int32 ASYNCSTART();  

        // 停止任务

        public delegate void ASYNCSTOP();  

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

        public delegate void ASYNCWAIT();  

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

        public delegate Int32 ASYNCSTATE();

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

        public delegate Int32 ASYNCMAXPROCS(Int32 num);  

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


        // 关闭动态库前调用此函数释放资源,否则关闭DLL会发生错误

        public delegate void UNLOAD();

        //--------------------------------以上为函数定义--------------------------------



        //--------------------------------函数变量--------------------------------

        static private DllInvoke dll;

        static private LOAD load;

        static private AUTH auth;

        static private LASTERR lastErr;

        static private FREESTRING freeString;

        static private TOTEXTFILE toTextFile;

        static private TOSTRING toString;

        static private HTTPTOSTRING httpToString;

        static private HTTPTOTEXTFILE httpToTextFile;

        static private ADDTASK addTask;

        static private ADDHTTPTASK addHttpTask;

        static private ASYNCSTART asyncStart;

        static private ASYNCSTOP asyncStop;

        static private ASYNCWAIT asyncWait;

        static private ASYNCSTATE asyncState;

        static private ASYNCMAXPROCS asyncMaxProcs;

        static private UNLOAD unload;

        //--------------------------------函数变量--------------------------------


        static public bool loadAllFun()

        {

            load = (LOAD)dll.Invoke("Load", typeof(LOAD));

            auth = (AUTH)dll.Invoke("Auth", typeof(AUTH));

            lastErr = (LASTERR)dll.Invoke("LastErr", typeof(LASTERR));

            freeString = (FREESTRING)dll.Invoke("FreeString", typeof(FREESTRING));

            toString = (TOSTRING)dll.Invoke("ToString", typeof(TOSTRING));

            toTextFile = (TOTEXTFILE)dll.Invoke("ToTextFile", typeof(TOTEXTFILE));

            httpToString = (HTTPTOSTRING)dll.Invoke("HttpToString", typeof(HTTPTOSTRING));

            httpToTextFile = (HTTPTOTEXTFILE)dll.Invoke("HttpToTextFile", typeof(HTTPTOTEXTFILE));

            addTask = (ADDTASK)dll.Invoke("AddTask", typeof(ADDTASK));

            addHttpTask = (ADDHTTPTASK)dll.Invoke("AddHttpTask", typeof(ADDHTTPTASK));

            asyncStart = (ASYNCSTART)dll.Invoke("AsyncStart", typeof(ASYNCSTART));

            asyncStop = (ASYNCSTOP)dll.Invoke("AsyncStop", typeof(ASYNCSTOP));

            asyncWait = (ASYNCWAIT)dll.Invoke("AsyncWait", typeof(ASYNCWAIT));

            asyncState = (ASYNCSTATE)dll.Invoke("AsyncState", typeof(ASYNCSTATE));

            asyncMaxProcs = (ASYNCMAXPROCS)dll.Invoke("AsyncMaxProcs", typeof(ASYNCMAXPROCS));

            unload = (UNLOAD)dll.Invoke("Unload", typeof(UNLOAD));


            if(load ==null || unload == null )

            {

                return false;

            }

            else

            {

                return true;

            }

        }


        public enum DllErrCode

        {

            TFE_OK = 0,

            TFE_UNKNOW = 1,

            TFE_FILE_NOTEXIST = 2,

            TFE_SAVE_ERROR = 3,

            TFE_OUTSIZE = 4,

            TFE_UNSUPPORTED = 5,

            TFE_ERROR_INTERFACE = 6,

            TFE_HTTP_ERR = 7,

            TFE_HTTP_FILE_NULL = 8,

            TFE_LICENCE_ERR = 9

        }


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

        public static string codeText(Int32 code)

        {

            switch ((DllErrCode)code)

            {

                case DllErrCode.TFE_OK:

                    return "ok";

                case DllErrCode.TFE_UNKNOW:

                    return "未知错误";

                case DllErrCode.TFE_FILE_NOTEXIST:

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

                case DllErrCode.TFE_SAVE_ERROR:

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

                case DllErrCode.TFE_OUTSIZE:

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

                case DllErrCode.TFE_UNSUPPORTED:

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

                case DllErrCode.TFE_ERROR_INTERFACE:

                    return "得到接口失败";

                case DllErrCode.TFE_HTTP_ERR:

                    return "HTTP下载文件失败";

                case DllErrCode.TFE_HTTP_FILE_NULL:

                    return "HTTP文件为空";

                case DllErrCode.TFE_LICENCE_ERR:

                    return "软件许可错误";

                default:

                    return "未知错误2";

            }

        }


        //转换为byte[] 为指针,输入byte[]可以避免忘记释放导致的问题

        static IntPtr stringToUtf8Pointer(byte[] bts)

{

            return Marshal.UnsafeAddrOfPinnedArrayElement(bts, 0);

        }


        //utf8指针转换为字符串

        static string utf8PointerToString(IntPtr p)

        {

            string s = Marshal.PtrToStringAnsi(p);

            //

            byte[] bytes = Encoding.UTF8.GetBytes(s);

            bytes = Encoding.Convert(Encoding.GetEncoding("UTF-8"), Encoding.Default, bytes);

            return Encoding.UTF8.GetString(bytes);

        }


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

        static void testToTextFile()

        {

            IntPtr infile = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\graccvs文件正文提取接口.pdf"));

            IntPtr outfile = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\out001.txt"));


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

            Int32 code = toTextFile(infile, outfile);

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

            if (code != (Int32)DllErrCode.TFE_OK)

            {

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

                string err = codeText(code);

                Console.WriteLine("error from code: %s\n", err);


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

                IntPtr p = lastErr();

                string err2 = utf8PointerToString(p);

                Console.WriteLine("error from dll: %s\n", err2);

            }

            else

            {

                Console.WriteLine("testToTextFile end\n");

            }

        }


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

        static void testToString()

        {

            byte[] bts = Encoding.UTF8.GetBytes("test\\简可信模板OCR识别工具帮助.docx");

            IntPtr infile = stringToUtf8Pointer(bts);

            IntPtr p = toString(infile); //返回UTF-8编码字符串

            try

            {

                string text = utf8PointerToString(p);

                Console.WriteLine("text=\n%s\n", text);

            }

            finally

            {

                freeString(p); // 务必调用freeString函数释放字符串内存

            }

        }


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

        static void testHttpToTextFile()

        {

            IntPtr rulPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("https://www.gaya-soft.cn/dfs/v2/简可信模板OCR识别工具帮助.docx"));

            IntPtr extPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(".docx"));

            IntPtr outFilePrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\out002.txt"));


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

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

            int code = httpToTextFile(rulPrt, extPrt, outFilePrt, timeout, IntPtr.Zero);

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

            if (code != (Int32)DllErrCode.TFE_OK)

            {

                string err = codeText(code);

                Console.WriteLine("error from code: %s\n", err);

            }

            else

            {

                Console.WriteLine("testHttpToTextFile end\n");

            }

        }


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

        static void testHttpToString()

        {

            IntPtr rulPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("https://www.gaya-soft.cn/dfs/v2/graccvs文件正文提取接口.pdf"));

            IntPtr extPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(".pdf"));

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

            IntPtr jsonParamsPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(jsonParams));

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


            IntPtr p = httpToString(rulPrt, extPrt, timeout, jsonParamsPrt); //返回UTF-8编码字符串

            try

            {

                string text = utf8PointerToString(p);

                Console.WriteLine("text=\n%s\n", text);

            }

            finally

            {

                freeString(p); // 务必调用freeString函数释放字符串内存

            }

        }


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

        // 文件提取任务

        static void asyncAddTask()

        {

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

            IntPtr inFnPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\graccvs文件正文提取接口.pdf"));

            IntPtr outFnPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\asyncOut001.txt"));

            addTask(inFnPrt, outFnPrt); // 一个文件任务


            IntPtr inFnPrt2 = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\Adobe Intro.ofd"));

            IntPtr outFnPrt2 = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\asyncOut002.txt"));

            addTask(inFnPrt2, outFnPrt2); // 一个文件任务

        }


        // Http文件提取任务

        static void asyncAddHttpTask()

        {

            // 可以增加N个任务

            IntPtr rulPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("https://www.gaya-soft.cn/dfs/v2/简可信模板OCR识别工具帮助.docx"));

            IntPtr extPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(".docx"));

            IntPtr outFnPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\asyncOut003.txt"));  

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

            addHttpTask(rulPrt, extPrt, outFnPrt, timeout, IntPtr.Zero);

        }


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

        static void asyncRun1()

        {

            // 开始任务

            int r = asyncStart();

            if (r == 1)

            {

                asyncWait(); // 等待任务全部结束

                Console.WriteLine("方式1--任务完成\n");

            }

            else if (r == 2)

            {

                Console.WriteLine("免费版不支持此功能\n");  

            }

            else if (r == 3)

            {

                Console.WriteLine("没有可以执行的任务\n");  

            }

            else if (r == 4)

            {

                Console.WriteLine("当前任务未完成\n");

            }

        }



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

        static void asyncRun2()

        {

            // 开始任务

            bool isOver = false;

            int r = asyncStart();

            if (r == 1)

            {

                System.DateTime start = new System.DateTime();

                // 5分钟后结束任务

                while (true)

                {

                    System.DateTime now = new System.DateTime();

                    TimeSpan ts = now - start;

                    // 5分钟后中断

                    if (ts.Minutes > 5 * 60)

                    {

                        break;

                    }

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

                    int x = asyncState();

                    if (x == 1)

                    {

                        Thread.Sleep(500);

                    }

                    else if (x == 99)

                    {

                        isOver = true; // 处理完成

                        break;

                    }

                    else

                    {

                        break;

                    }

                }

                //

                if (!isOver)

                {

                    asyncStop(); // 结束任务

                }

                Console.WriteLine("方式2--任务完成\n");

            }

            else if (r == 2)

            {

                Console.WriteLine("免费版不支持此功能\n");

            }

            else if (r == 3)

            {

                Console.WriteLine("没有可以执行的任务\n");

            }

            else if (r == 4)

            {

                Console.WriteLine("当前任务未完成\n");

            }

        }


        static void asyncTest()

        {

            asyncMaxProcs(8); // 同时运行8个任务

                              //

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

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

                                      // 执行任务--方式1

            asyncRun1();


            // 执行任务--方式2

            asyncAddTask();

            asyncAddHttpTask();

            asyncRun2();

        }

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


        //

        static void Main(string[] args)

        {

            dll = new DllInvoke("graccvs64.dll"); //默认64位系统,32位DLL或者接口更新请到官网

            if (dll == null)

            {

                Console.WriteLine("load dll error!");

                return;

            }


            if (!loadAllFun() )

            {

                Console.WriteLine("load dll error!");

                return;

            }

            //dll初始化函数

            IntPtr tempPath = stringToUtf8Pointer(Encoding.UTF8.GetBytes("test\\"));  

            load(tempPath);


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

            IntPtr corpPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes("Beij Gaya"));

            IntPtr licTextPrt = stringToUtf8Pointer(Encoding.UTF8.GetBytes(""));

            auth(corpPrt, licTextPrt);//企业版这里设置授权文本


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

            testToTextFile();

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

            testToString();


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

            testHttpToTextFile();

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

            testHttpToString();


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

            asyncTest();


            //dll关闭DLL前执行此函数

            unload();


            Console.WriteLine("test over!");

            Console.ReadLine();

        }

    }

}


/*

  graccvs文件正文分析接口---北京盖亚软件有限公司版权所有

  -----------------------------------------------------------

本接口为Lucene/CLucene, Elasticsearch, Sphinx等全文检索工具,OA, ERP, CRM等其他系统提供文件摘要及搜索前置服务。

本接口提取文本速度快,质量高,跨平台,支持多任务并发。提供多种接口及示例。


  1: 接口提供多种操作系统动态链接库

  windows平台: (32bit和64bit)

    dll格式及GCC、VC、JAVA、C#、delphi调用示例


  linux平台:支持(64bit)内核版本4.4及以上, 中标麒麟7.0.0(64bit)及以上

注:内核版本(64bit)4.4以下也可能使用此接口, 具体以实际情况为准

    so格式文件及GCC、JAVA调用示例,其他语言完善中


安卓平台:

    arr格式文件及Android Studio调用示例


苹果ios平台:

注:Mac os参考ios系统调用

    xcframework格式文件及xcode+objective-c调用示例


  2:接口现在可以提取的文件类型有(新增提取文件类型请关注官网):

    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个文件


  3:返回字符串及文本文件为UTF-8编码


  4:提取最大文件默认为200M,配置文件可以设置此阀值


  5:企业版本提供异步多线程接口,可以同时批量处理多个文件


  6:接口详细文档参考 https://www.gaya-soft.cn/grhelp/


  7:接口提供 VC C++, GCC, C#, Java, Delphi, 安卓Java, 苹果C++调用接口示例

示例下载地址https://www.gaya-soft.cn/download/


  8:免费版本只提取40%到80%的正文文本内容,且有盖亚软件标识。

软件注册请参考官网https://www.gaya-soft.cn/grhelp/lic.html

*/

--------------------------------------------------------------------------------------------------------------

(文中代码来源:北京盖亚软件有限公司,详见 http://www.gaya-soft.cn/ )

***** 敬请关注交流,批评指正 *****

--------------------------------------------------------------------------------------------------------------

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

推荐阅读更多精彩内容