打印

【原创】一个go语言小项目实例:通过select监控channel并阻塞

[复制链接]
4211|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keer_zu|  楼主 | 2019-1-17 09:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 keer_zu 于 2019-1-17 15:13 编辑

(利用这个简单小原理实现的一个小项目,监控最新创建的,拥有多级深度的文件夹变化内容,并将最新产生的文件通过tcp或者http发送给连上来的tcp客户端和http服务端:
这个小项目源码




这是一个简单的例子:


package main

import (
"fmt"
"time"
)

func generateString(strings chan string) {
    time.Sleep(3*time.Second)
    strings <- "Monday"
    time.Sleep(5*time.Second)
    strings <- "Tuesday"
    time.Sleep(3*time.Second)
    strings <- "Wednesday"
    time.Sleep(5*time.Second)
    strings <- "Thursday"
    strings <- "Friday"
    strings <- "Saturday"
    strings <- "Sunday"
    close(strings)
}


func monitor(cancel chan string) {

    var stop bool = false
        for {
            time.Sleep(1*time.Second)
            fmt.Println("i am alive!")
            select {
                case can := <- cancel:
                    if can == "cancel" {
                        fmt.Println("break!")
                        stop = true
                        break
                    }
                    
            }

            if stop {
                break
            }
        }


    fmt.Println("good bye!")
}

func main() {
    //strings := make(chan string) // 无缓冲channel
    cancel_sig := make(chan string)

    //go generateString(strings)

    //for s := range strings {
    //    fmt.Println(s)
    //}

    go monitor(cancel_sig)

    time.Sleep(10*time.Second)

    cancel_sig <- "cancel"

    for {
        time.Sleep(5*time.Second)
        fmt.Println("go away!")
        break
    }
}



如果有多个channel,也可以被一个select监听,例如:


package notify;

import (
    "github.com/fsnotify/fsnotify"
    "github.com/smtp-http/filemonitor_macmini/conn"
    "github.com/smtp-http/filemonitor_macmini/config"
    "log"
    "fmt"
    "path/filepath"
    "path"
    "io/ioutil"
    "sync"
)

type FileMonitor struct {
    m_tcpserver *conn.TcpServer
}

var instance *FileMonitor
var once sync.Once

func GetFileMonitorInstance() *FileMonitor {
    once.Do(func() {
        instance = &FileMonitor{}
    })
    return instance
}

func (f *FileMonitor)SetTcpserver(server *conn.TcpServer) {
    f.m_tcpserver = server
}

func (f *FileMonitor)Monitor(cancel chan string) {

    var stop bool = false

    //创建一个监控对象
    watch, err := fsnotify.NewWatcher();
    if err != nil {
        log.Fatal(err);
    }
    defer watch.Close();
    //
    err = watch.Add(config.GetConfig().Path);
    if err != nil {
        log.Fatal(err);
    }
    //我们另启一个goroutine来处理监控对象的事件

    for {
        fmt.Println("--- 1")
        if stop {
            break
        }
        select {
            case ev := <-watch.Events:
                {
                    //判断事件发生的类型,如下5种
                    // Create 创建
                    // Write 写入
                    // Remove 删除
                    // Rename 重命名
                    // Chmod 修改权限
                    if ev.Op&fsnotify.Create == fsnotify.Create {
                        fmt.Println("创建文件 : ", ev.Name);
                    }
                    if ev.Op&fsnotify.Write == fsnotify.Write {
                        fmt.Println("写入文件 : ", ev.Name);
                        paths, fileName := filepath.Split(ev.Name)
                        fmt.Println(paths, fileName) //获取路径中的目录及文件名 E:\data\ test.txt
                        fmt.Println(filepath.Base(ev.Name)) //获取路径中的文件名test.txt
                        

                        if path.Ext(ev.Name) == config.GetConfig().FileExtension {
                            fmt.Println(path.Ext(ev.Name)) //获取路径中的文件的后缀 .txt
                            b, err := ioutil.ReadFile(ev.Name)
                            if err != nil {
                                fmt.Print(err)
                            }
                            fmt.Println(b)
                            //str := string(b)
                        
                            f.m_tcpserver.Notify(b)
                            configure := config.GetConfig()
                            if configure.HttpEnable == true {
                                httpClient := conn.GetHttpClientInstance()
                                httpClient.HttpPost(b)
                            }

                        }

                        
                    }

                    if ev.Op&fsnotify.Remove == fsnotify.Remove {
                        fmt.Println("删除文件 : ", ev.Name);
                    }

                    if ev.Op&fsnotify.Rename == fsnotify.Rename {
                        fmt.Println("重命名文件 : ", ev.Name);
                    }
                    
                    if ev.Op&fsnotify.Chmod == fsnotify.Chmod {
                        fmt.Println("修改权限 : ", ev.Name);
                    }
                }

            case can := <- cancel:
                if can == "cancel" {
                    fmt.Println("break!")
                    stop = true
                    break
                }
            case err := <-watch.Errors:
                {
                    log.Println("error : ", err);
                    return;
                }
        }
    }

    fmt.Println("good bye!")
}









相关帖子

沙发
keer_zu|  楼主 | 2019-1-17 11:19 | 只看该作者
github代码持续更新中。。。。。


代码参考:monitor.go

使用特权

评论回复
板凳
icecut| | 2019-1-18 10:07 | 只看该作者
strings是一个标准包名.尽量避免使用

使用特权

评论回复
地板
keer_zu|  楼主 | 2019-1-18 13:28 | 只看该作者
icecut 发表于 2019-1-18 10:07
strings是一个标准包名.尽量避免使用

使用特权

评论回复
5
zzdsj2| | 2019-1-19 14:02 | 只看该作者
666

使用特权

评论回复
6
jndnhdndfn| | 2019-6-18 20:09 | 只看该作者
也有啊,前天不是你也到一个很狂的贴里去了吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1352

主题

12436

帖子

53

粉丝