diff --git a/README.md b/README.md
index 633a52623a8f37782f72641586ad63d3766900ae..407f0479bfadc03aef7a575df39a9fe5e4db0fc7 100644
--- a/README.md
+++ b/README.md
@@ -50,5 +50,5 @@
9. [Hardcodet.NotifyIcon.Wpf](https://www.nuget.org/packages/Hardcodet.NotifyIcon.Wpf/)
#### 仓库地址
-[github](https://github.com/liulei901112/TextLocator)
-[gitee](https://gitee.com/liulei901112/TextLocator)
\ No newline at end of file
+* [github](https://github.com/liulei901112/TextLocator)
+* [gitee](https://gitee.com/liulei901112/TextLocator)
\ No newline at end of file
diff --git a/TextLocator/App.xaml.cs b/TextLocator/App.xaml.cs
index a96c8b7f05e3a96317f22d9f9f70a4a5749ae085..50b6dee7a14bb72fd0b2186af0646edb44ab40af 100644
--- a/TextLocator/App.xaml.cs
+++ b/TextLocator/App.xaml.cs
@@ -35,7 +35,10 @@ namespace TextLocator
// 初始化线程池大小
InitThreadPoolSize();
- // 初始化文件信息服务引擎
+ // 初始化配置
+ InitAppConfig();
+
+ // 初始化文件服务引擎
InitFileInfoServiceEngine();
}
@@ -93,7 +96,6 @@ namespace TextLocator
AppUtil.WriteValue("ThreadPool", "MaxSize", AppConst.THREAD_POOL_MAX_SIZE + "");
}
-
///
/// 初始化文件信息服务引擎
///
@@ -124,6 +126,15 @@ namespace TextLocator
log.Error("文件服务工厂初始化错误:" + ex.Message, ex);
}
}
+
+ ///
+ /// 初始化AppConfig
+ ///
+ private void InitAppConfig()
+ {
+ // 保存线程池
+ AppUtil.WriteValue("AppConfig", "FileReadTimeout", AppConst.FILE_READ_TIMEOUT + "");
+ }
#endregion
#region 异常处理
diff --git a/TextLocator/Core/AppConst.cs b/TextLocator/Core/AppConst.cs
index 8c39bc3c6a1c234f351766c2a030dd630f680487..fa4a0cf6f11ccf172b98191c6d0702c3a92f3d9c 100644
--- a/TextLocator/Core/AppConst.cs
+++ b/TextLocator/Core/AppConst.cs
@@ -21,13 +21,9 @@ namespace TextLocator.Core
///
public static readonly int THREAD_POOL_MAX_SIZE = int.Parse(AppUtil.ReadValue("ThreadPool", "MaxSize", "64"));
///
- /// 应用目录
- ///
- public static readonly string APP_DIR = AppDomain.CurrentDomain.BaseDirectory;
- ///
/// App.ini路径:_AppDir\\_AppName\\Index\\
///
- public static readonly string APP_INDEX_DIR = Path.Combine(APP_DIR, "Index");
+ public static readonly string APP_INDEX_DIR = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Index");
///
/// 分词器
/// new Lucene.Net.Analysis.Cn.ChineseAnalyzer();
@@ -50,6 +46,10 @@ namespace TextLocator.Core
/// 搜索最大值限制
///
public static readonly int MAX_COUNT_LIMIT = int.Parse(AppUtil.ReadValue("AppConfig", "MaxCountLimit", "100"));
+ ///
+ /// 文件读取超时时间,单位:秒
+ ///
+ public static readonly int FILE_READ_TIMEOUT = int.Parse(AppUtil.ReadValue("AppConfig", "FileReadTimeout", "600"));
///
/// 匹配特殊字符
@@ -70,7 +70,7 @@ namespace TextLocator.Core
///
/// 匹配排除关键词
///
- public static readonly Regex REGEX_EXCLUDE_KEYWORD = new Regex(@"(\$RECYCLE|360REC|C:\\(SYSTEM|PROGRAM FILES)|TEMP\\|TMP\\|SYSTEM VOLUME INFOMATION|\.(.*)\\|\{(.*)\})");
+ public static readonly Regex REGEX_EXCLUDE_KEYWORD = new Regex(@"(\$RECYCLE|360REC|SYSTEM|TEMP|SYSTEM VOLUME INFOMATION|\{(.*)\})");
///
/// 匹配开始字符
///
@@ -88,5 +88,6 @@ namespace TextLocator.Core
/// 文件内容缩略信息截取值
///
public const int FILE_CONTENT_SUB_LENGTH = 120;
+
}
}
diff --git a/TextLocator/Factory/FileInfoServiceFactory.cs b/TextLocator/Factory/FileInfoServiceFactory.cs
index e9227dd18bdb382c56f52bf96be54b6ae259fef3..9464f368ddde8641f73456b604916a4ac8858a96 100644
--- a/TextLocator/Factory/FileInfoServiceFactory.cs
+++ b/TextLocator/Factory/FileInfoServiceFactory.cs
@@ -1,16 +1,20 @@
using log4net;
using System;
using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using TextLocator.Core;
using TextLocator.Enums;
using TextLocator.Service;
+using TextLocator.Util;
namespace TextLocator.Factory
{
- ///
- /// 文件信息服务工厂
- ///
- public class FileInfoServiceFactory
- {
+ ///
+ /// 文件信息服务工厂
+ ///
+ public class FileInfoServiceFactory
+ {
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
///
@@ -18,12 +22,40 @@ namespace TextLocator.Factory
///
private static Dictionary services = new Dictionary();
+ #region 工厂方法
+ ///
+ /// 获取文件内容
+ ///
+ ///
+ ///
+ public static string GetFileContent(string filePath)
+ {
+ // 获取文件服务对象
+ IFileInfoService fileInfoService = GetFileInfoService(FileTypeUtil.GetFileType(filePath));
+
+ string content;
+ // 读取文件内容
+ content = WaitTimeout(fileInfoService.GetFileContent, filePath, TimeSpan.FromSeconds(AppConst.FILE_READ_TIMEOUT));
+ return content;
+ }
+
+ ///
+ /// 注册服务实例
+ ///
+ /// 文件类型
+ /// 服务实例
+ public static void Register(FileType fileType, IFileInfoService fileInfoService)
+ {
+ log.Debug((int)fileType + ":" + fileType.ToString() + " 引擎注册");
+ services.Add(fileType, fileInfoService);
+ }
+
///
/// 根据项目类型获取服务实例
///
/// 文件类型
///
- public static IFileInfoService GetFileInfoService(FileType fileType)
+ private static IFileInfoService GetFileInfoService(FileType fileType)
{
try
{
@@ -35,16 +67,48 @@ namespace TextLocator.Factory
throw new Exception("暂无[" + fileType.ToString() + "]服务实例, 返回默认其他类型文件服务实例");
}
}
+ #endregion
+ #region 超时函数
///
- /// 注册服务实例
+ /// 有参数,有反回值方法
///
- /// 文件类型
- /// 服务实例
- public static void Register(FileType fileType, IFileInfoService fileInfoService)
+ ///
+ ///
+ public delegate string TimeoutDelegate(string param);
+
+ ///
+ /// 有参数,有反回值超时方法
+ ///
+ /// 执行方法
+ /// 超时时间
+ /// 执行参数
+ /// 反回一个string类型方法
+ public static string WaitTimeout(TimeoutDelegate method, string param, TimeSpan timeout)
{
- log.Debug((int)fileType + ":" + fileType.ToString() + " 引擎注册");
- services.Add(fileType, fileInfoService);
+ string obj = null;
+ AutoResetEvent are = new AutoResetEvent(false);
+ Thread t = new Thread(delegate () { obj = method(param); are.Set(); });
+ t.Start();
+ Wait(t, timeout, are);
+ return obj;
+ }
+
+ ///
+ /// 等待方法执行完成,或超时
+ ///
+ ///
+ ///
+ ///
+ private static void Wait(Thread t, TimeSpan timeout, WaitHandle are)
+ {
+ WaitHandle[] ares = new WaitHandle[] { are };
+ int index = WaitHandle.WaitAny(ares, timeout);
+ if ((index != 0) && t.IsAlive) // 如果不是执行完成的信号,并且,线程还在执行,那么,结束这个线程
+ {
+ t.Abort();
+ }
}
+ #endregion
}
}
diff --git a/TextLocator/Index/IndexCore.cs b/TextLocator/Index/IndexCore.cs
index 1fa1fba9edea28d9e7a27f70bfa4f2154383573b..826cb2fbdd9455e7346a7df61f220ec687260836 100644
--- a/TextLocator/Index/IndexCore.cs
+++ b/TextLocator/Index/IndexCore.cs
@@ -1,5 +1,4 @@
using log4net;
-using Lucene.Net.Documents;
using Lucene.Net.Index;
using System;
using System.Collections.Generic;
@@ -48,46 +47,37 @@ namespace TextLocator.Index
///
/// 回调函数
///
- private static Callback _callback;
-
+ private static volatile Callback _callback;
#region 索引写入器
///
/// 索引写入初始化(FSDirectory表示索引存放在硬盘上,RAMDirectory表示放在内存上)
///
- private static IndexWriter _indexWriter;
- ///
- /// 索引写入器锁
- ///
- private static volatile object _writerLock = new object();
+ private static volatile IndexWriter _indexWriter;
+
///
/// 创建索引写入器
///
- private static IndexWriter GetIndexWriter()
+ private static void CreateIndexWriter()
{
if (_indexWriter == null)
{
- lock(_writerLock)
- {
- if (_indexWriter == null)
- {
- // 索引写入初始化(FSDirectory表示索引存放在硬盘上,RAMDirectory表示放在内存上)
- _indexWriter = new IndexWriter(
- // 索引目录
- AppConst.INDEX_DIRECTORY,
- // 分词器
- AppConst.INDEX_ANALYZER,
- // 是否创建
- _create,
- // 字段限制
- IndexWriter.MaxFieldLength.UNLIMITED);
-
- // 设置Buffer内存上限,默认值16MB
- _indexWriter.SetRAMBufferSizeMB(512);
- }
- }
+ // 索引写入初始化(FSDirectory表示索引存放在硬盘上,RAMDirectory表示放在内存上)
+ _indexWriter = new IndexWriter(
+ // 索引目录
+ AppConst.INDEX_DIRECTORY,
+ // 分词器
+ AppConst.INDEX_ANALYZER,
+ // 是否创建
+ _create,
+ // 字段限制
+ IndexWriter.MaxFieldLength.UNLIMITED);
+
+ // 设置Buffer内存上限,默认值16MB
+ _indexWriter.SetRAMBufferSizeMB(512);
+ // 设置Buffer内存文档上线
+ _indexWriter.SetMaxBufferedDocs(10000);
}
- return _indexWriter;
}
///
@@ -95,20 +85,17 @@ namespace TextLocator.Index
///
private static void CloseIndexWriter()
{
- lock (_writerLock)
+ if (_indexWriter != null)
{
- if (_indexWriter != null)
- {
- // 销毁索引写入器
- _indexWriter.Dispose();
- }
+ // 销毁索引写入器
+ _indexWriter.Dispose();
+ // 索引写入器置为NULL
+ _indexWriter = null;
}
- // 置为NULL
- _indexWriter = null;
}
#endregion
- #region 创建文件索引
+ #region 创建索引
///
/// 创建索引
///
@@ -142,7 +129,7 @@ namespace TextLocator.Index
}
// 创建索引写入器
- GetIndexWriter();
+ CreateIndexWriter();
using (MutipleThreadResetEvent resetEvent = new MutipleThreadResetEvent(_totalCount))
{
@@ -155,34 +142,36 @@ namespace TextLocator.Index
{
continue;
}
-
// 加入线程池
ThreadPool.QueueUserWorkItem(new WaitCallback(CreateIndexTask), new TaskInfo()
{
FilePath = filePath,
ResetEvent = resetEvent
});
-
}
+
// 等待所有线程结束
resetEvent.WaitAll();
}
- try
+ lock (locker)
{
- // 索引优化
- GetIndexWriter().Optimize();
+ try
+ {
+ // 索引优化
+ _indexWriter.Optimize();
+ }
+ catch (Exception ex)
+ {
+ log.Error("索引优化错误:" + ex.Message, ex);
+ }
- // 关闭并销毁索引写入器
+ // 关闭索引写入器
CloseIndexWriter();
-
- // 手动GC
- ManualGC();
- }
- catch (Exception ex)
- {
- log.Error(ex.Message, ex);
}
+
+ // 手动GC
+ ManualGC();
}
///
@@ -203,16 +192,11 @@ namespace TextLocator.Index
// 跳过的文件闪烁
_callback(skipMsg, CalcFinishRatio(_finishCount, _totalCount));
- lock (locker)
- {
- _finishCount++;
- }
+ // 完成数量+1
+ Interlocked.Increment(ref _finishCount);
- try
- {
- resetEvent.SetOne();
- }
- catch { }
+ // 当前任务执行完成,唤醒等待线程继续执行
+ resetEvent.SetOne();
#if !DEBUG
log.Debug(skipMsg);
@@ -231,11 +215,12 @@ namespace TextLocator.Index
TaskInfo taskInfo = obj as TaskInfo;
try
{
- // 文件路径
- string filePath = taskInfo.FilePath;
// 解析时间
var taskMark = TaskTime.StartNew();
+ // 文件路径
+ string filePath = taskInfo.FilePath;
+
// 写入已索引标记
AppUtil.WriteValue("FileIndex", filePath, "1");
@@ -251,98 +236,110 @@ namespace TextLocator.Index
// 根据文件路径获取文件类型(自定义文件类型分类)
FileType fileType = FileTypeUtil.GetFileType(filePath);
- string filePathSub = filePath;
- if (filePath.Length > 60)
+ // 截取文件路径
+ string subFilePath = filePath;
+ if (subFilePath.Length > 65)
{
- filePathSub = filePath.Substring(0, 30) + "......" + filePath.Substring(filePath.Length - 30);
+ subFilePath = filePath.Substring(0, 30) + "......" + filePath.Substring(filePath.Length - 30);
}
- StringBuilder msg = new StringBuilder("[" + _finishCount * 1.0F + "/" + _totalCount + "] => 引擎:" + (int)fileType + ",文件:" + filePathSub);
+ StringBuilder msg = new StringBuilder("[" + _finishCount * 1.0F + "/" + _totalCount + "] => 引擎:" + (int)fileType + ",文件:" + subFilePath);
// 文件内容
- string content = FileInfoServiceFactory.GetFileInfoService(fileType).GetFileContent(filePath);
+ string content = FileInfoServiceFactory.GetFileContent(filePath);
msg.Append(",解析:" + taskMark.ConsumeTime + "秒");
-
- // 缩略信息
- string breviary = AppConst.REGEX_LINE_BREAKS_AND_WHITESPACE.Replace(content, "");
- if (breviary.Length > AppConst.FILE_CONTENT_SUB_LENGTH)
+ // 判断文件内容
+ if (!string.IsNullOrEmpty(content))
{
- breviary = breviary.Substring(0, AppConst.FILE_CONTENT_SUB_LENGTH) + "...";
- }
+ // 缩略信息
+ string breviary = AppConst.REGEX_LINE_BREAKS_AND_WHITESPACE.Replace(content, "");
+ if (breviary.Length > AppConst.FILE_CONTENT_SUB_LENGTH)
+ {
+ breviary = breviary.Substring(0, AppConst.FILE_CONTENT_SUB_LENGTH) + "...";
+ }
- // 文件标记
- string fileMark = MD5Util.GetMD5Hash(filePath); //fileInfo.DirectoryName + fileInfo.CreationTime.ToString();
+ // 文件标记
+ string fileMark = MD5Util.GetMD5Hash(filePath);
- // 索引时间
- taskMark = TaskTime.StartNew();
+ // 索引时间
+ taskMark = TaskTime.StartNew();
- lock (locker)
- {
- try
+ lock (locker)
{
- // 当索引文件中含有与filemark相等的field值时,会先删除再添加,以防出现重复
- // GetIndexWriter().DeleteDocuments(new Term("FileMark", fileMark));
-
- Document doc = new Document();
+ // 创建索引Doc对象
+ Lucene.Net.Documents.Document doc = new Lucene.Net.Documents.Document();
// 不分词建索引
- doc.Add(new Field("FileMark", fileMark, Field.Store.YES, Field.Index.NOT_ANALYZED, Field.TermVector.YES));
- doc.Add(new Field("FileType", fileType.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
- doc.Add(new Field("FileSize", fileSize + "", Field.Store.YES, Field.Index.NOT_ANALYZED));
- doc.Add(new Field("Breviary", breviary, Field.Store.YES, Field.Index.NOT_ANALYZED));
- doc.Add(new Field("CreateTime", createTime, Field.Store.YES, Field.Index.NOT_ANALYZED));
+ doc.Add(new Lucene.Net.Documents.Field("FileMark", fileMark, Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
+ doc.Add(new Lucene.Net.Documents.Field("FileType", fileType.ToString(), Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
+ doc.Add(new Lucene.Net.Documents.Field("FileSize", fileSize + "", Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
+ doc.Add(new Lucene.Net.Documents.Field("Breviary", breviary, Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
+ doc.Add(new Lucene.Net.Documents.Field("CreateTime", createTime, Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
// ANALYZED分词建索引
- doc.Add(new Field("FileName", fileName, Field.Store.YES, Field.Index.ANALYZED));
- doc.Add(new Field("FilePath", filePath, Field.Store.YES, Field.Index.ANALYZED));
- doc.Add(new Field("Content", content, Field.Store.NO, Field.Index.ANALYZED));
-
- // GetIndexWriter().AddDocument(doc);
- // 索引存在时更新,不存在时添加
- GetIndexWriter().UpdateDocument(new Term("FileMark", fileMark), doc);
-
- /*if (_finishCount % 1000 == 0 || _finishCount == _totalCount)
- {
- // 索引刷新
- GetIndexWriter().Optimize(10000);
- }*/
- }
- catch (Exception ex)
- {
- log.Error(filePath + " -> " + ex.Message, ex);
-
- Type ext = ex.GetType();
+ doc.Add(new Lucene.Net.Documents.Field("FileName", fileName, Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.ANALYZED));
+ doc.Add(new Lucene.Net.Documents.Field("FilePath", filePath, Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.ANALYZED));
+ doc.Add(new Lucene.Net.Documents.Field("Content", content, Lucene.Net.Documents.Field.Store.NO, Lucene.Net.Documents.Field.Index.ANALYZED));
- if (ext == typeof(NullReferenceException) || ext == typeof(OutOfMemoryException))
- {
- // 关闭并销毁索引写入器
- CloseIndexWriter();
- }
-
- // 手动GC
- ManualGC();
- }
- finally
- {
- // 完成数+1
- _finishCount++;
+ // 执行删除、添加逻辑
+ AddDocument(filePath, doc);
}
+ msg.Append(",索引:" + taskMark.ConsumeTime + "秒");
+ }
+ else
+ {
+ msg.Append(",返回内容为空不创建索引。。。");
}
- msg.Append(",索引:" + taskMark.ConsumeTime + "秒");
// 执行状态回调
- // taskInfo.Callback(msg.ToString(), CalcFinishRatio(_finishCount, taskInfo.TotalCount));
_callback(msg.ToString(), CalcFinishRatio(_finishCount, _totalCount));
log.Debug(msg);
}
- catch { }
+ catch (Exception ex)
+ {
+ log.Error(ex.Message, ex);
+ }
finally
{
- // 标记当前任务完成,唤醒等待线程继续执行
+ // 完成数量+1
+ Interlocked.Increment(ref _finishCount);
+
+ // 当前任务执行完成,唤醒等待线程继续执行
taskInfo.ResetEvent.SetOne();
}
}
+
+ ///
+ /// 添加文件索引Doc
+ ///
+ /// 文件路径
+ /// 文件索引Doc
+ private static void AddDocument(string filePath, Lucene.Net.Documents.Document doc)
+ {
+ try
+ {
+ // 文件标记
+ string fileMark = MD5Util.GetMD5Hash(filePath);
+
+ _indexWriter.UpdateDocument(new Term("FileMark", fileMark), doc);
+ }
+ catch(Exception ex)
+ {
+ log.Error(filePath + " -> " + ex.Message + " => 重启索引写入器!", ex);
+
+
+ // 关闭索引写入器
+ CloseIndexWriter();
+
+ // 创建索引写入器
+ CreateIndexWriter();
+
+ log.Debug(filePath + " -> 重新执行添加操作");
+
+ AddDocument(filePath, doc);
+ }
+ }
#endregion
#region 完成比例计算器
diff --git a/TextLocator/Index/MutipleThreadResetEvent.cs b/TextLocator/Index/MutipleThreadResetEvent.cs
index a395a443d26499b47fc1af8a2229be7db9ed8ea0..28560637d4ae1c4d75e0da97ecaf1a8ecbce2ae8 100644
--- a/TextLocator/Index/MutipleThreadResetEvent.cs
+++ b/TextLocator/Index/MutipleThreadResetEvent.cs
@@ -18,15 +18,15 @@ namespace TextLocator.Index
///
/// 人工重置的事件
///
- private readonly ManualResetEvent done;
+ private readonly ManualResetEvent _event;
///
/// 任务总数
///
- private readonly int total;
+ private readonly int _total;
///
- /// 任务当前剩余数量
+ /// 剩余数量
///
- private long current;
+ private volatile int _current;
///
/// 构造函数
@@ -34,9 +34,9 @@ namespace TextLocator.Index
/// 需要等待执行的线程总数
public MutipleThreadResetEvent(int total)
{
- this.total = total;
- this.current = total;
- this.done = new ManualResetEvent(false);
+ this._total = total;
+ this._current = total;
+ this._event = new ManualResetEvent(false);
}
///
@@ -45,10 +45,10 @@ namespace TextLocator.Index
public void SetOne()
{
// Interlocked 原子操作类 ,此处将计数器减1
- if (Interlocked.Decrement(ref current) == 0)
+ if (Interlocked.Decrement(ref _current) == 0)
{
//当所以等待线程执行完毕时,唤醒等待的线程
- done.Set();
+ _event.Set();
}
}
@@ -57,7 +57,7 @@ namespace TextLocator.Index
///
public void WaitAll()
{
- done.WaitOne();
+ _event.WaitOne();
}
///
@@ -65,7 +65,7 @@ namespace TextLocator.Index
///
public void Dispose()
{
- done.Dispose();
+ ((IDisposable)_event).Dispose();
}
}
}
diff --git a/TextLocator/MainWindow.xaml.cs b/TextLocator/MainWindow.xaml.cs
index dedf870cad2e806e54c122f3e0fb655a4a4a8c70..5568a2e07eaa0c6bdb5778cae50fb86199c1564b 100644
--- a/TextLocator/MainWindow.xaml.cs
+++ b/TextLocator/MainWindow.xaml.cs
@@ -908,7 +908,7 @@ namespace TextLocator
else
{
// 文件内容
- content = FileInfoServiceFactory.GetFileInfoService(fileInfo.FileType).GetFileContent(fileInfo.FilePath);
+ content = FileInfoServiceFactory.GetFileContent(fileInfo.FilePath);
// 写入缓存
CacheUtil.Add(fileInfo.FilePath, content);
@@ -985,7 +985,9 @@ namespace TextLocator
private void MatchWords_Unchecked(object sender, RoutedEventArgs e)
{
BeforeSearch();
- }
+ }
+
+
///
/// 优化按钮
@@ -1001,6 +1003,8 @@ namespace TextLocator
}
build = true;
+ ShowStatus("开始更新索引,请稍等...");
+
BuildIndex(false);
}
@@ -1016,7 +1020,6 @@ namespace TextLocator
Message.ShowWarning("MessageContainer", "索引构建中,不能重复执行!");
return;
}
-
if (CheckIndexExist(false))
{
var result = await MessageBoxR.ConfirmInContainer("DialogContaioner", "确定要重建索引嘛?时间可能比较久哦!", "提示");
@@ -1027,8 +1030,15 @@ namespace TextLocator
}
}
+ if (build)
+ {
+ Message.ShowWarning("MessageContainer", "索引构建中,请稍等。");
+ return;
+ }
build = true;
+ ShowStatus("开始重建索引,请稍等...");
+
BuildIndex(true);
}
diff --git a/TextLocator/Properties/AssemblyInfo.cs b/TextLocator/Properties/AssemblyInfo.cs
index 40dfbed18fd9bd85156ba64433e2b80384f90162..93deef0f125d064b40cc4164e484c5c23d3b2fe1 100644
--- a/TextLocator/Properties/AssemblyInfo.cs
+++ b/TextLocator/Properties/AssemblyInfo.cs
@@ -49,8 +49,8 @@ using System.Windows;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.6")]
-[assembly: AssemblyFileVersion("1.2.6.0")]
+[assembly: AssemblyVersion("1.2.7")]
+[assembly: AssemblyFileVersion("1.2.7.0")]
// log4net
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
\ No newline at end of file
diff --git a/TextLocator/Service/ExcelFileService.cs b/TextLocator/Service/ExcelFileService.cs
index 01418872a040a27bbdaf0893cf61ae78e4d4f115..d2e1d06aeddae45e6cd517ce5fdf13540832550b 100644
--- a/TextLocator/Service/ExcelFileService.cs
+++ b/TextLocator/Service/ExcelFileService.cs
@@ -26,111 +26,111 @@ namespace TextLocator.Service
{
try
{
- // =========== Spire.XLS ===========
- // 创建Workbook对象
- using (Spire.Xls.Workbook workbook = new Spire.Xls.Workbook())
+ // =========== NPIO ===========
+ // 文件流
+ using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
- // 加载Excel文档
- workbook.LoadFromFile(filePath);
- StringBuilder builder = new StringBuilder();
- if (workbook != null)
+ // 获取扩展名
+ string extName = Path.GetExtension(filePath);
+ // 读取IWorkbook
+ IWorkbook readWorkbook = null;
+ switch (extName)
{
- WorksheetsCollection sheets = workbook.Worksheets;
- if (sheets != null && sheets.Count > 0)
+ // 把xls写入workbook中 2003版本
+ case ".xls":
+ readWorkbook = new HSSFWorkbook(fileStream);
+ break;
+ // 把xlsx 写入workbook中 2007版本
+ case ".xlsx":
+ readWorkbook = new XSSFWorkbook(fileStream);
+ break;
+ default:
+ break;
+ }
+
+ if (readWorkbook != null)
+ {
+ StringBuilder builder = new StringBuilder();
+ // 获取表
+ var sheetCount = readWorkbook.NumberOfSheets;
+ if (sheetCount > 0)
{
- // 获取工作表
- for (int i = 0; i < sheets.Count; i++)
+ for (int i = 0; i < sheetCount; i++)
{
- using (Spire.Xls.Worksheet sheet = sheets[i])
+ // 得到sheet数据
+ ISheet sheet = readWorkbook.GetSheetAt(i);
+ if (sheet != null)
{
- // 行
- for (int j = sheet.FirstRow; j < sheet.LastRow; j++)
+ // 获取行数
+ var rowCount = sheet.LastRowNum;
+ // 解析行数据
+ for (int j = 0; j <= rowCount; j++)
{
- using (Spire.Xls.CellRange row = sheet.Rows[j])
+ // 得到row数据
+ IRow row = sheet.GetRow(j);
+ if (row != null)
{
- // 列
- for (int k = 0; k < row.Columns.Length; k++)
+ // 解析列数据
+ for (int k = 0; k < row.LastCellNum; k++)
{
- builder.Append(row.Columns[k].Value2.ToString() + " ");
+ // 得到cell数据
+ ICell cell = row.GetCell(k);
+ // 获取某行某列对应的单元格数据
+ builder.Append(cell + " ");
}
+ // 换行
+ builder.AppendLine();
}
- builder.AppendLine();
}
}
}
}
+ readWorkbook.Close();
+
+ content = builder.ToString();
}
- content = builder.ToString();
}
}
catch (Exception spirex)
{
log.Error(filePath + " -> " + spirex.Message + " Spire.Xls解析错误,尝试NPIO", spirex);
- // =========== NPIO ===========
try
{
- // 文件流
- using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+ // =========== Spire.XLS ===========
+ // 创建Workbook对象
+ using (Spire.Xls.Workbook workbook = new Spire.Xls.Workbook())
{
- // 获取扩展名
- string extName = Path.GetExtension(filePath);
- // 读取IWorkbook
- IWorkbook readWorkbook = null;
- switch (extName)
+ // 加载Excel文档
+ workbook.LoadFromFile(filePath);
+ StringBuilder builder = new StringBuilder();
+ if (workbook != null)
{
- // 把xls写入workbook中 2003版本
- case ".xls":
- readWorkbook = new HSSFWorkbook(fileStream);
- break;
- // 把xlsx 写入workbook中 2007版本
- case ".xlsx":
- readWorkbook = new XSSFWorkbook(fileStream);
- break;
- default:
- break;
- }
-
- if (readWorkbook != null)
- {
- StringBuilder builder = new StringBuilder();
- // 获取表
- var sheetCount = readWorkbook.NumberOfSheets;
- if (sheetCount > 0)
+ WorksheetsCollection sheets = workbook.Worksheets;
+ if (sheets != null && sheets.Count > 0)
{
- for (int i = 0; i < sheetCount; i++)
+ // 获取工作表
+ for (int i = 0; i < sheets.Count; i++)
{
- // 得到sheet数据
- ISheet sheet = readWorkbook.GetSheetAt(i);
- if (sheet != null)
+ using (Spire.Xls.Worksheet sheet = sheets[i])
{
- // 获取行数
- var rowCount = sheet.LastRowNum;
- // 解析行数据
- for (int j = 0; j <= rowCount; j++)
+ // 行
+ for (int j = sheet.FirstRow; j < sheet.LastRow; j++)
{
- // 得到row数据
- IRow row = sheet.GetRow(j);
- if (row != null)
+ using (Spire.Xls.CellRange row = sheet.Rows[j])
{
- // 解析列数据
- for (int k = 0; k < row.LastCellNum; k++)
+ // 列
+ for (int k = 0; k < row.Columns.Length; k++)
{
- // 得到cell数据
- ICell cell = row.GetCell(k);
- // 获取某行某列对应的单元格数据
- builder.Append(cell + " ");
+ builder.Append(row.Columns[k].Value2.ToString() + " ");
}
- // 换行
- builder.AppendLine();
}
+ builder.AppendLine();
}
}
}
}
- readWorkbook.Close();
-
- content = builder.ToString();
}
+ content = builder.ToString();
}
}
catch (Exception ex)
diff --git a/TextLocator/SettingWindow.xaml b/TextLocator/SettingWindow.xaml
new file mode 100644
index 0000000000000000000000000000000000000000..22cafdcd53297095455cf7cc5e90139cd2ad73a3
--- /dev/null
+++ b/TextLocator/SettingWindow.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TextLocator/SettingWindow.xaml.cs b/TextLocator/SettingWindow.xaml.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7d07b57f2da20018d5abf18512f7e2620149aaba
--- /dev/null
+++ b/TextLocator/SettingWindow.xaml.cs
@@ -0,0 +1,72 @@
+using log4net;
+using Newtonsoft.Json;
+using Rubyer;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using TextLocator.HotKey;
+using TextLocator.Util;
+
+namespace TextLocator
+{
+ ///
+ /// SettingWindow.xaml 的交互逻辑
+ ///
+ public partial class SettingWindow : Window
+ {
+ private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ ///
+ /// 单例
+ ///
+ private static SettingWindow _instance;
+
+ public SettingWindow()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// 创建系统参数设置窗体实例
+ ///
+ ///
+ public static SettingWindow CreateInstance()
+ {
+ return _instance ?? (_instance = new SettingWindow());
+ }
+
+ ///
+ /// 加载完毕
+ ///
+ ///
+ ///
+ private void Window_Loaded(object sender, RoutedEventArgs e)
+ {
+ }
+
+ #region 保存并关闭
+ ///
+ /// 保存并关闭
+ ///
+ ///
+ ///
+ private void SaveClose_Click(object sender, RoutedEventArgs e)
+ {
+ this.Close();
+ }
+ #endregion
+
+ ///
+ /// 窗体关闭
+ ///
+ ///
+ ///
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ _instance = null;
+ }
+ }
+}
diff --git a/TextLocator/TextLocator.csproj b/TextLocator/TextLocator.csproj
index c83d00e1fc0f0f7f72a1866e8e0994d9d6f3d0a4..a27cc9c3b743cfd578385465af6f7d36bc5a1ffc 100644
--- a/TextLocator/TextLocator.csproj
+++ b/TextLocator/TextLocator.csproj
@@ -157,6 +157,9 @@
MSBuild:Compile
Designer
+
+ SettingWindow.xaml
+
HotkeyWindow.xaml
@@ -210,6 +213,10 @@
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
@@ -323,17 +330,5 @@
-
-
- False
- Microsoft .NET Framework 4.6 %28x86 和 x64%29
- true
-
-
- False
- .NET Framework 3.5 SP1
- false
-
-
\ No newline at end of file