txt阅读器系列:
任何小说阅读器,都免不了要有一个书架功能,而所谓书架,其实就是一个文件夹,通过对文件夹进行递归式地搜索,就可以找到所有txt
文件,并进行统一管理。
所以,下面建立一个书柜类,其中必不可少的就是书柜的根目录。
internal class BookShelf
{
string root; //根目录
string name; //最上层的文件夹
List<BookShelf> childs;
string[] books;
public BookShelf(string root)
{
init(root);
}
public void init(string root)
{
this.root = root;
name = Path.GetFileName(root);
foreach (var d in Directory.GetDirectories(root))
{
if (getAllChilds(d).Length == 0)
continue;
childs.Add(new BookShelf(d));
}
books = getAllChilds(root);
}
public string[] getAllChilds(string path)
{
return Directory
.GetFiles(path, "*.txt", SearchOption.AllDirectories)
.Select(f => Path.GetFileName(f))
.ToArray();
}
public bool isBookShelf(string path)
{
var txts = Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories);
return txts.Length > 0;
}
}
其中,init
是初始化函数,主要包括两个步骤,一是检索当前文件夹中是否还有文件夹,如果有文件夹,则判断这个文件夹是否有书籍,如果有书籍,就新增一个子书柜,否则跳过。
在检测完文件夹之后,再检测文件,通过getAllChilds,将所有txt为后缀的文件作为书籍加入其中。getAllChilds函数中,用到了这种比较现代的链式编程,第一步用Directory.GetFiles获取所有后缀为txt的路径,然后挑选这些文件,并返回这些文件的文件名,最后转换为数字形式。
考虑到大多数情况下,导入一个文件夹,都需要经过文件夹对话框,所以需要再写一个无参数输入的构造函数。但这里有一个问题,即WPF并不支持文件夹对话框,为了实现功能,需要在工具->nuget包管理器中下载,名字是FolderBrowserForWPF,然后就可以调用了,直须注意引用一下
using FolderBrowserForWPF;
然后再写一个构造函数
public BookShelf()
{
var fbd = new Dialog();
if (fbd.ShowDialog() != true)
return;
init(fbd.FileName);
}
为了验证是否真的实现了这个书柜,需要重写一下ToString
函数,用于打印书柜中所有的书籍
public string ToString()
{
string info = $"{name}\r\n";
if(childs != null)
foreach (var bs in childs)
info += $"{bs}\r\n";
if(books != null)
foreach (var book in books)
info += $"-{book}\r\n";
return info;
}
然后就可以在主窗口程序中调用这个功能了,首先为导入
按钮添加btnLoadFolder_Click
事件,
BookShelf bookShelf;
private void btnLoadFolder_Click(object sender, RoutedEventArgs e)
{
bookShelf = new BookShelf();
txtInfo.Text = bookShelf.ToString();
}
然后执行,效果如下