using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Text;
namespace FileSearch
{
public partial class Form1 : Form
{
string RemoteIndexPath = Application.StartupPath + @"\remote_index_path.txt";
string IndexPath = Application.StartupPath + @"\index.dat";
List<string> RawItems = new List<string>();
int VisibleCount = 100;
int RawItemCount = 0;
string WriteTime = "";
public Form1()
{
InitializeComponent();
if (!IndexLoad()) return;
LoadPosition();
var delayExecute = new DelayExecute();
delayExecute.Execute += (s, e) => SetupDatasource();
textBox1.TextChanged += (s, e) => delayExecute.ReserveExecute();
listBox1.MouseDoubleClick += (s, e) => OpenFile(s, e);
this.FormClosing += (s, e) => SavePosition();
}
private bool IndexLoad()
{
if (!File.Exists(RemoteIndexPath)) // リモートインデックスを指定するファイルがない場合
{
MessageBox.Show("インデックスファイルが見つかりませんでした。");
return false;
}
string remoteIndexPath = File.ReadAllText(RemoteIndexPath);
if (!File.Exists(IndexPath) && !File.Exists(remoteIndexPath)) // ローカル、リモートにない場合
{
MessageBox.Show("インデックスファイルが見つかりませんでした。");
return false;
}
else if (File.Exists(IndexPath) && !File.Exists(remoteIndexPath)) // ローカルにあって、リモートにない場合
{
RawItems = File.ReadAllLines(IndexPath).ToList();
RawItemCount = RawItems.Count();
WriteTime = File.GetLastWriteTime(IndexPath).ToString("yyyy/MM/dd HH:mm:ss");
}
else if (!File.Exists(IndexPath) && File.Exists(remoteIndexPath)) // ローカルになくて、リモートにある場合
{
File.Copy(remoteIndexPath, IndexPath);
RawItems = File.ReadAllLines(IndexPath).ToList();
RawItemCount = RawItems.Count();
WriteTime = File.GetLastWriteTime(IndexPath).ToString("yyyy/MM/dd HH:mm:ss");
}
else if (File.Exists(IndexPath) && File.Exists(remoteIndexPath)) // ローカル、リモートにある場合
{
if (File.GetLastWriteTime(IndexPath) < File.GetLastWriteTime(remoteIndexPath)) // リモートの方が最新の場合
{
if (DialogResult.Yes == MessageBox.Show("最新のインデックスファイルが存在します。更新しますか?","", MessageBoxButtons.YesNo))
{
File.Copy(remoteIndexPath, IndexPath, true);
}
RawItems = File.ReadAllLines(IndexPath).ToList();
RawItemCount = RawItems.Count();
WriteTime = File.GetLastWriteTime(IndexPath).ToString("yyyy/MM/dd HH:mm:ss");
}
else // ローカルの方が最新の場合
{
RawItems = File.ReadAllLines(IndexPath).ToList();
RawItemCount = RawItems.Count();
WriteTime = File.GetLastWriteTime(IndexPath).ToString("yyyy/MM/dd HH:mm:ss");
}
}
return true;
}
private void SetupDatasource()
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
string needle = "";
Invoke((MethodInvoker)(() => {
needle = textBox1.Text;
}));
IEnumerable<string> items = new List<string>(VisibleCount);
if (needle == "")
{
items = RawItems.Take(VisibleCount);
}
else
{
List<string> tmpList = new List<string>(RawItems);
tmpList.Capacity = RawItemCount;
foreach (string tmpString in needle.Split('|'))
{
tmpList = tmpList.AsParallel().Where(x => x.ToLower().Contains(tmpString.ToLower())).ToList();
}
items = tmpList.Take(VisibleCount);
}
var itemClassList = new System.Collections.Concurrent.ConcurrentBag<ItemClass>();
System.Threading.Tasks.Parallel.ForEach(items, item =>
{
itemClassList.Add(new ItemClass()
{
DisplayItemPath = Path.GetFileName(item) + " . . . ■" + Path.GetDirectoryName(item),
ItemPath = item
});
});
stopwatch.Stop();
Invoke((MethodInvoker)(() => {
listBox1.DataSource = itemClassList.ToList();
listBox1.DisplayMember = "DisplayItemPath";
Text = items.Count() + "/" + RawItemCount + "件表示 (" + stopwatch.ElapsedMilliseconds.ToString() + "ms):" + WriteTime + "インデックス";
}));
}
private void OpenFile(object sender, MouseEventArgs e)
{
var itemPath = ((ItemClass)listBox1.SelectedItem).ItemPath;
if (!File.Exists(itemPath))
{
MessageBox.Show("ファイルを開くことができませんでした。");
return;
}
if (ModifierKeys == Keys.Control)
{
System.Diagnostics.Process.Start(Path.GetDirectoryName(itemPath));
}
else
{
System.Diagnostics.Process.Start(itemPath);
}
}
private void LoadPosition()
{
if (!File.Exists(Application.StartupPath + @"\dat.xml")) return;
this.StartPosition = FormStartPosition.Manual;
XmlSerializer xs = new XmlSerializer(typeof(List<int>));
using (StreamReader sr = new StreamReader(Application.StartupPath + @"\dat.xml", Encoding.UTF8))
{
try
{
List<int> items = (List<int>)xs.Deserialize(sr);
this.Width = (int)items[0];
this.Height = (int)items[1];
this.Top = (int)items[2];
this.Left = (int)items[3];
}
catch
{
this.StartPosition = FormStartPosition.WindowsDefaultLocation;
}
}
}
private void SavePosition()
{
if (this.WindowState == FormWindowState.Maximized) return;
XmlSerializer xs = new XmlSerializer(typeof(List<int>));
using (StreamWriter sw = new StreamWriter(Application.StartupPath + @"\dat.xml", false, Encoding.UTF8))
{
List<int> items = new List<int>();
items.Add(this.Width);
items.Add(this.Height);
items.Add(this.Top);
items.Add(this.Left);
xs.Serialize(sw, items);
}
}
}
struct ItemClass
{
public string DisplayItemPath { set; get; }
public string ItemPath { set; get; }
}
class DelayExecute
{
public event EventHandler Execute;
private int DelayTime = 500;
System.Threading.Timer Timer;
public DelayExecute()
{
Timer = new System.Threading.Timer(x => {
Execute(this, EventArgs.Empty);
});
}
public void ReserveExecute()
{
Timer.Change(DelayTime, System.Threading.Timeout.Infinite);
}
}
}