refact traverse and inotify

This commit is contained in:
zhangzihao 2020-12-25 20:06:20 +08:00
parent 36c675e701
commit f06e9e3614
4 changed files with 235 additions and 0 deletions

151
index/inotify.cpp Normal file
View File

@ -0,0 +1,151 @@
#include "inotify.h"
InotifyManagerRefact::InotifyManagerRefact(const QString& path) : Traverse_BFS(path)
{
// dirPath = new QMap<QString, QStringList>();
m_fd = inotify_init();
qDebug() << "m_fd----------->" <<m_fd;
num2string.insert(IN_ACCESS, "IN_ACCESS");
num2string.insert(IN_MODIFY, "IN_MODIFY");
num2string.insert(IN_ATTRIB, "IN_ATTRIB");
num2string.insert(IN_CLOSE_WRITE, "IN_CLOSE_WRITE");
num2string.insert(IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE");
num2string.insert(IN_CLOSE, "IN_CLOSE");
num2string.insert(IN_OPEN, "IN_OPEN");
num2string.insert(IN_MOVED_FROM, "IN_MOVED_FROM");
num2string.insert(IN_MOVED_TO, "IN_MOVED_TO");
num2string.insert(IN_MOVE, "IN_MOVE");
num2string.insert(IN_CREATE, "IN_CREATE");
num2string.insert(IN_DELETE, "IN_DELETE");
num2string.insert(IN_DELETE_SELF, "IN_DELETE_SELF");
num2string.insert(IN_MOVE_SELF, "IN_MOVE_SELF");
num2string.insert(IN_UNMOUNT, "IN_UNMOUNT");
num2string.insert(IN_Q_OVERFLOW, "IN_Q_OVERFLOW");
num2string.insert(IN_IGNORED, "IN_IGNORED");
this->mlm = new MessageListManager();
return;
}
InotifyManagerRefact::~InotifyManagerRefact(){
delete this->mlm;
this->mlm = nullptr;
// delete dirPath;
// dirPath = nullptr;
}
void InotifyManagerRefact::DoSomething(const QFileInfo& fileInfo){
this->mlm->AddMessage(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString(bool((fileInfo.isDir()))));
if(fileInfo.isDir()){
this->AddWatch(fileInfo.absoluteFilePath());
}
}
bool InotifyManagerRefact::AddWatch(const QString &path){
//m_fd = inotify_init();
// qDebug() << "m_fd: " <<m_fd;
//int ret = inotify_add_watch(m_fd, path.toStdString().c_str(), IN_ALL_EVENTS);
int ret = inotify_add_watch(m_fd, path.toStdString().c_str(), (IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | IN_DELETE));
if (ret == -1) {
qDebug() << "AddWatch error:" << path;
return false;
}
currentPath[ret] = path;
//qDebug() << "Watch:" << path;
return true;
}
bool InotifyManagerRefact::RemoveWatch(const QString &path){
int ret = inotify_rm_watch(m_fd, currentPath.key(path));
if (ret){
qDebug() << "remove path error";
return false;
}
// qDebug() << "remove path: " << path;
for (QMap<int, QString>::Iterator i = currentPath.begin(); i != currentPath.end();){
if (i.value().length() > path.length()){
if (i.value().mid(0, path.length()) == path){
qDebug() << i.value();
/*--------------------------------*/
//在此调用删除索引
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(path));
/*--------------------------------*/
currentPath.erase(i++);
}
else{
i++;
}
}
else{
i++;
}
}
qDebug() << path;
//这个貌似不用删先mark一下
//currentPath.remove(currentPath.key(path));
return true;
}
void InotifyManagerRefact::run(){
char * p;
char buf[BUF_LEN] __attribute__((aligned(8)));
ssize_t numRead;
for (;;) { /* Read events forever */
numRead = read(m_fd, buf, BUF_LEN);
if (numRead == 0) {
qDebug() << "read() from inotify fd returned 0!";
}
if (numRead == -1) {
qDebug() << "read";
}
qDebug() << "Read " << numRead << " bytes from inotify fd";
/* Process all of the events in buffer returned by read() */
for (p = buf; p < buf + numRead;) {
struct inotify_event * event = reinterpret_cast<inotify_event *>(p);
if(event->name[0] != '.'){
// if(true){
//这个位运算不要在意,只是懒得把文件夹、文件和事件排列组合了,只是看一下事件的类型
qDebug() << "Read Event: " << num2string[(event->mask & 0x0000ffff)] << currentPath[event->wd] << QString(event->name) << event->cookie << event->wd;
//num2string[event->mask & 0x0000ffff]
// IndexGenerator::getInstance()->creatAllIndex(new QStringList(currentPath[event->wd] + event->name));
/*--------------------------------*/
//传创建或移动过来的文件路径
if((event->mask & IN_CREATE) | (event->mask & IN_MOVED_TO)){
//添加监视要先序遍历先添加top节点
if (event->mask & IN_ISDIR){
AddWatch(currentPath[event->wd] + '/' + event->name);
this->setPath(currentPath[event->wd] + '/' + event->name);
Traverse();
}
// else {
//IndexGenerator::getInstance()->creatAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
this->mlm->AddMessage(QVector<QString>() << event->name << (currentPath[event->wd] + '/' + event->name) << QString(bool((event->mask & IN_ISDIR))));
this->mlm->SendMessage();
// }
}
else if((event->mask & IN_DELETE) | (event->mask & IN_MOVED_FROM)){
if (event->mask & IN_ISDIR){
RemoveWatch(currentPath[event->wd] + '/' + event->name);
}
// else {
//这里调用删除索引
this->mlm->AddMessage(QVector<QString>() << event->name << (currentPath[event->wd] + '/' + event->name) << QString(bool((event->mask & IN_ISDIR))));
this->mlm->SendDeleteMessage();
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
// }
}
/*--------------------------------*/
}
p += sizeof(struct inotify_event) + event->len;
}
}
}

35
index/inotify.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef INOTIFY_H
#define INOTIFY_H
#include <QObject>
#include <QThread>
#include <unistd.h>
#include <sys/inotify.h>
#include "traverse_bfs.h"
#include "messagelist-manager.h"
#define BUF_LEN 1024
class InotifyManagerRefact : public QThread, public Traverse_BFS
{
Q_OBJECT
public:
explicit InotifyManagerRefact(const QString&);
~InotifyManagerRefact();
bool AddWatch(const QString&);
bool RemoveWatch(const QString&);
virtual void DoSomething(const QFileInfo &) final;
Q_SIGNALS:
protected:
void run() override;
private:
QString *m_watch_path;
int m_fd;
QMap<int, QString> currentPath;
QMap<int, QString> num2string;
MessageListManager* mlm;
QMap<QString, QStringList>* dirPath;
};
#endif // INOTIFY_H

29
index/traverse_bfs.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "traverse_bfs.h"
Traverse_BFS::Traverse_BFS(const QString& path)
{
this->path = path;
}
void Traverse_BFS::Traverse(){
QQueue<QString> bfs;
bfs.enqueue(this->path);
QFileInfoList list;
QDir dir;
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
dir.setSorting(QDir::DirsFirst);
while (!bfs.empty()) {
dir.setPath(bfs.dequeue());
list = dir.entryInfoList();
for (auto i : list){
if (i.isDir()){
bfs.enqueue(i.absoluteFilePath());
}
DoSomething(i);
}
}
}
void Traverse_BFS::setPath(const QString& path){
this->path = path;
}

20
index/traverse_bfs.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef TRAVERSE_BFS_H
#define TRAVERSE_BFS_H
#include <QDebug>
#include <QDir>
#include <QQueue>
class Traverse_BFS
{
public:
explicit Traverse_BFS(const QString&);
void Traverse();
virtual void DoSomething(const QFileInfo&) = 0;
void setPath(const QString&);
private:
QString path = "/home";
};
#endif // TRAVERSE_BFS_H